2010-01-16 04:35:54 +08:00
|
|
|
//===- CXCursor.cpp - Routines for manipulating CXCursors -----------------===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2010-01-16 22:00:32 +08:00
|
|
|
// This file defines routines for manipulating CXCursors. It should be the
|
|
|
|
// only file that has internal knowledge of the encoding of the data in
|
|
|
|
// CXCursor.
|
2010-01-16 04:35:54 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2010-11-18 07:24:11 +08:00
|
|
|
#include "CXTranslationUnit.h"
|
2010-01-16 04:35:54 +08:00
|
|
|
#include "CXCursor.h"
|
2010-11-16 09:56:27 +08:00
|
|
|
#include "CXString.h"
|
2010-01-20 08:23:15 +08:00
|
|
|
#include "clang/Frontend/ASTUnit.h"
|
2010-01-16 04:35:54 +08:00
|
|
|
#include "clang/AST/Decl.h"
|
2010-09-01 07:48:11 +08:00
|
|
|
#include "clang/AST/DeclCXX.h"
|
2010-01-16 05:56:13 +08:00
|
|
|
#include "clang/AST/DeclObjC.h"
|
2011-10-06 15:00:54 +08:00
|
|
|
#include "clang/AST/DeclTemplate.h"
|
2010-01-16 05:56:13 +08:00
|
|
|
#include "clang/AST/Expr.h"
|
2010-09-14 06:52:57 +08:00
|
|
|
#include "clang/AST/ExprCXX.h"
|
2011-10-06 15:00:54 +08:00
|
|
|
#include "clang/AST/ExprObjC.h"
|
2010-11-02 07:26:51 +08:00
|
|
|
#include "clang-c/Index.h"
|
2010-01-16 08:36:30 +08:00
|
|
|
#include "llvm/Support/ErrorHandling.h"
|
2010-01-16 04:35:54 +08:00
|
|
|
|
|
|
|
using namespace clang;
|
2010-09-14 06:52:57 +08:00
|
|
|
using namespace cxcursor;
|
2010-01-16 04:35:54 +08:00
|
|
|
|
2012-05-01 03:06:49 +08:00
|
|
|
CXCursor cxcursor::MakeCXCursorInvalid(CXCursorKind K, CXTranslationUnit TU) {
|
2010-01-21 07:34:41 +08:00
|
|
|
assert(K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid);
|
2012-05-01 03:06:49 +08:00
|
|
|
CXCursor C = { K, 0, { 0, 0, TU } };
|
2010-01-21 07:34:41 +08:00
|
|
|
return C;
|
2010-01-16 04:35:54 +08:00
|
|
|
}
|
|
|
|
|
2010-02-18 11:09:07 +08:00
|
|
|
static CXCursorKind GetCursorKind(const Attr *A) {
|
|
|
|
assert(A && "Invalid arguments!");
|
|
|
|
switch (A->getKind()) {
|
|
|
|
default: break;
|
2010-06-17 07:43:53 +08:00
|
|
|
case attr::IBAction: return CXCursor_IBActionAttr;
|
|
|
|
case attr::IBOutlet: return CXCursor_IBOutletAttr;
|
|
|
|
case attr::IBOutletCollection: return CXCursor_IBOutletCollectionAttr;
|
2011-09-14 01:39:31 +08:00
|
|
|
case attr::Final: return CXCursor_CXXFinalAttr;
|
|
|
|
case attr::Override: return CXCursor_CXXOverrideAttr;
|
2011-10-13 17:41:32 +08:00
|
|
|
case attr::Annotate: return CXCursor_AnnotateAttr;
|
2011-12-07 06:05:01 +08:00
|
|
|
case attr::AsmLabel: return CXCursor_AsmLabelAttr;
|
2010-02-18 11:09:07 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return CXCursor_UnexposedAttr;
|
|
|
|
}
|
|
|
|
|
2010-11-16 16:15:36 +08:00
|
|
|
CXCursor cxcursor::MakeCXCursor(const Attr *A, Decl *Parent,
|
|
|
|
CXTranslationUnit TU) {
|
2010-02-18 11:09:07 +08:00
|
|
|
assert(A && Parent && TU && "Invalid arguments!");
|
2011-10-06 15:00:54 +08:00
|
|
|
CXCursor C = { GetCursorKind(A), 0, { Parent, (void*)A, TU } };
|
2010-02-18 11:09:07 +08:00
|
|
|
return C;
|
|
|
|
}
|
|
|
|
|
2010-11-16 16:15:36 +08:00
|
|
|
CXCursor cxcursor::MakeCXCursor(Decl *D, CXTranslationUnit TU,
|
2011-10-06 15:00:54 +08:00
|
|
|
SourceRange RegionOfInterest,
|
2010-11-02 07:26:51 +08:00
|
|
|
bool FirstInDeclGroup) {
|
2010-01-25 08:40:30 +08:00
|
|
|
assert(D && TU && "Invalid arguments!");
|
2011-10-06 15:00:54 +08:00
|
|
|
|
|
|
|
CXCursorKind K = getCursorKindForDecl(D);
|
|
|
|
|
|
|
|
if (K == CXCursor_ObjCClassMethodDecl ||
|
|
|
|
K == CXCursor_ObjCInstanceMethodDecl) {
|
|
|
|
int SelectorIdIndex = -1;
|
|
|
|
// Check if cursor points to a selector id.
|
|
|
|
if (RegionOfInterest.isValid() &&
|
|
|
|
RegionOfInterest.getBegin() == RegionOfInterest.getEnd()) {
|
|
|
|
SmallVector<SourceLocation, 16> SelLocs;
|
|
|
|
cast<ObjCMethodDecl>(D)->getSelectorLocs(SelLocs);
|
|
|
|
SmallVector<SourceLocation, 16>::iterator
|
|
|
|
I=std::find(SelLocs.begin(), SelLocs.end(),RegionOfInterest.getBegin());
|
|
|
|
if (I != SelLocs.end())
|
|
|
|
SelectorIdIndex = I - SelLocs.begin();
|
|
|
|
}
|
|
|
|
CXCursor C = { K, SelectorIdIndex,
|
|
|
|
{ D, (void*)(intptr_t) (FirstInDeclGroup ? 1 : 0), TU }};
|
|
|
|
return C;
|
|
|
|
}
|
|
|
|
|
|
|
|
CXCursor C = { K, 0, { D, (void*)(intptr_t) (FirstInDeclGroup ? 1 : 0), TU }};
|
2010-01-21 07:34:41 +08:00
|
|
|
return C;
|
2010-01-16 08:36:30 +08:00
|
|
|
}
|
|
|
|
|
2011-10-06 15:00:54 +08:00
|
|
|
CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent, CXTranslationUnit TU,
|
|
|
|
SourceRange RegionOfInterest) {
|
2010-01-25 08:40:30 +08:00
|
|
|
assert(S && TU && "Invalid arguments!");
|
2010-01-20 07:20:36 +08:00
|
|
|
CXCursorKind K = CXCursor_NotImplemented;
|
|
|
|
|
|
|
|
switch (S->getStmtClass()) {
|
|
|
|
case Stmt::NoStmtClass:
|
|
|
|
break;
|
2011-10-06 03:00:14 +08:00
|
|
|
|
2010-01-20 07:20:36 +08:00
|
|
|
case Stmt::CaseStmtClass:
|
2011-10-06 03:00:14 +08:00
|
|
|
K = CXCursor_CaseStmt;
|
|
|
|
break;
|
|
|
|
|
2010-01-20 07:20:36 +08:00
|
|
|
case Stmt::DefaultStmtClass:
|
2011-10-06 03:00:14 +08:00
|
|
|
K = CXCursor_DefaultStmt;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::IfStmtClass:
|
|
|
|
K = CXCursor_IfStmt;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::SwitchStmtClass:
|
|
|
|
K = CXCursor_SwitchStmt;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::WhileStmtClass:
|
|
|
|
K = CXCursor_WhileStmt;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::DoStmtClass:
|
|
|
|
K = CXCursor_DoStmt;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::ForStmtClass:
|
|
|
|
K = CXCursor_ForStmt;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::GotoStmtClass:
|
|
|
|
K = CXCursor_GotoStmt;
|
|
|
|
break;
|
|
|
|
|
2010-01-20 07:20:36 +08:00
|
|
|
case Stmt::IndirectGotoStmtClass:
|
2011-10-06 03:00:14 +08:00
|
|
|
K = CXCursor_IndirectGotoStmt;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::ContinueStmtClass:
|
|
|
|
K = CXCursor_ContinueStmt;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::BreakStmtClass:
|
|
|
|
K = CXCursor_BreakStmt;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::ReturnStmtClass:
|
|
|
|
K = CXCursor_ReturnStmt;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::AsmStmtClass:
|
|
|
|
K = CXCursor_AsmStmt;
|
|
|
|
break;
|
2012-06-12 04:47:18 +08:00
|
|
|
|
|
|
|
case Stmt::MSAsmStmtClass:
|
|
|
|
K = CXCursor_MSAsmStmt;
|
|
|
|
break;
|
2011-10-06 03:00:14 +08:00
|
|
|
|
|
|
|
case Stmt::ObjCAtTryStmtClass:
|
|
|
|
K = CXCursor_ObjCAtTryStmt;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::ObjCAtCatchStmtClass:
|
|
|
|
K = CXCursor_ObjCAtCatchStmt;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::ObjCAtFinallyStmtClass:
|
|
|
|
K = CXCursor_ObjCAtFinallyStmt;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::ObjCAtThrowStmtClass:
|
|
|
|
K = CXCursor_ObjCAtThrowStmt;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::ObjCAtSynchronizedStmtClass:
|
|
|
|
K = CXCursor_ObjCAtSynchronizedStmt;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::ObjCAutoreleasePoolStmtClass:
|
|
|
|
K = CXCursor_ObjCAutoreleasePoolStmt;
|
|
|
|
break;
|
|
|
|
|
2010-01-20 07:20:36 +08:00
|
|
|
case Stmt::ObjCForCollectionStmtClass:
|
2011-10-06 03:00:14 +08:00
|
|
|
K = CXCursor_ObjCForCollectionStmt;
|
|
|
|
break;
|
|
|
|
|
2010-01-20 07:20:36 +08:00
|
|
|
case Stmt::CXXCatchStmtClass:
|
2011-10-06 03:00:14 +08:00
|
|
|
K = CXCursor_CXXCatchStmt;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::CXXTryStmtClass:
|
|
|
|
K = CXCursor_CXXTryStmt;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::CXXForRangeStmtClass:
|
|
|
|
K = CXCursor_CXXForRangeStmt;
|
|
|
|
break;
|
|
|
|
|
2011-04-28 09:08:34 +08:00
|
|
|
case Stmt::SEHTryStmtClass:
|
2011-10-06 03:00:14 +08:00
|
|
|
K = CXCursor_SEHTryStmt;
|
|
|
|
break;
|
|
|
|
|
2011-04-28 09:08:34 +08:00
|
|
|
case Stmt::SEHExceptStmtClass:
|
2011-10-06 03:00:14 +08:00
|
|
|
K = CXCursor_SEHExceptStmt;
|
|
|
|
break;
|
|
|
|
|
2011-04-28 09:08:34 +08:00
|
|
|
case Stmt::SEHFinallyStmtClass:
|
2011-10-06 03:00:14 +08:00
|
|
|
K = CXCursor_SEHFinallyStmt;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::ArrayTypeTraitExprClass:
|
|
|
|
case Stmt::AsTypeExprClass:
|
2011-10-11 10:20:01 +08:00
|
|
|
case Stmt::AtomicExprClass:
|
2011-10-06 03:00:14 +08:00
|
|
|
case Stmt::BinaryConditionalOperatorClass:
|
|
|
|
case Stmt::BinaryTypeTraitExprClass:
|
2012-02-24 15:38:34 +08:00
|
|
|
case Stmt::TypeTraitExprClass:
|
2011-10-06 03:00:14 +08:00
|
|
|
case Stmt::CXXBindTemporaryExprClass:
|
|
|
|
case Stmt::CXXDefaultArgExprClass:
|
|
|
|
case Stmt::CXXScalarValueInitExprClass:
|
|
|
|
case Stmt::CXXUuidofExprClass:
|
|
|
|
case Stmt::ChooseExprClass:
|
|
|
|
case Stmt::DesignatedInitExprClass:
|
|
|
|
case Stmt::ExprWithCleanupsClass:
|
|
|
|
case Stmt::ExpressionTraitExprClass:
|
|
|
|
case Stmt::ExtVectorElementExprClass:
|
|
|
|
case Stmt::ImplicitCastExprClass:
|
|
|
|
case Stmt::ImplicitValueInitExprClass:
|
2011-06-22 01:03:29 +08:00
|
|
|
case Stmt::MaterializeTemporaryExprClass:
|
2011-10-06 03:00:14 +08:00
|
|
|
case Stmt::ObjCIndirectCopyRestoreExprClass:
|
|
|
|
case Stmt::OffsetOfExprClass:
|
|
|
|
case Stmt::ParenListExprClass:
|
|
|
|
case Stmt::PredefinedExprClass:
|
|
|
|
case Stmt::ShuffleVectorExprClass:
|
|
|
|
case Stmt::UnaryExprOrTypeTraitExprClass:
|
|
|
|
case Stmt::UnaryTypeTraitExprClass:
|
|
|
|
case Stmt::VAArgExprClass:
|
2012-03-07 04:06:06 +08:00
|
|
|
case Stmt::ObjCArrayLiteralClass:
|
|
|
|
case Stmt::ObjCDictionaryLiteralClass:
|
2012-04-19 08:25:12 +08:00
|
|
|
case Stmt::ObjCBoxedExprClass:
|
2012-03-07 04:06:06 +08:00
|
|
|
case Stmt::ObjCSubscriptRefExprClass:
|
2011-10-06 03:00:14 +08:00
|
|
|
K = CXCursor_UnexposedExpr;
|
|
|
|
break;
|
|
|
|
|
2011-11-06 17:01:30 +08:00
|
|
|
case Stmt::OpaqueValueExprClass:
|
|
|
|
if (Expr *Src = cast<OpaqueValueExpr>(S)->getSourceExpr())
|
|
|
|
return MakeCXCursor(Src, Parent, TU, RegionOfInterest);
|
|
|
|
K = CXCursor_UnexposedExpr;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::PseudoObjectExprClass:
|
|
|
|
return MakeCXCursor(cast<PseudoObjectExpr>(S)->getSyntacticForm(),
|
|
|
|
Parent, TU, RegionOfInterest);
|
|
|
|
|
2011-10-06 03:00:14 +08:00
|
|
|
case Stmt::CompoundStmtClass:
|
|
|
|
K = CXCursor_CompoundStmt;
|
2010-01-20 07:20:36 +08:00
|
|
|
break;
|
2012-04-14 08:33:13 +08:00
|
|
|
|
2011-10-06 03:00:14 +08:00
|
|
|
case Stmt::NullStmtClass:
|
|
|
|
K = CXCursor_NullStmt;
|
2010-09-10 08:22:18 +08:00
|
|
|
break;
|
2012-04-14 08:33:13 +08:00
|
|
|
|
2011-10-06 03:00:14 +08:00
|
|
|
case Stmt::LabelStmtClass:
|
|
|
|
K = CXCursor_LabelStmt;
|
|
|
|
break;
|
2012-04-14 08:33:13 +08:00
|
|
|
|
|
|
|
case Stmt::AttributedStmtClass:
|
|
|
|
K = CXCursor_UnexposedStmt;
|
|
|
|
break;
|
|
|
|
|
2011-10-06 03:00:14 +08:00
|
|
|
case Stmt::DeclStmtClass:
|
|
|
|
K = CXCursor_DeclStmt;
|
|
|
|
break;
|
2012-04-14 08:33:13 +08:00
|
|
|
|
2011-10-06 03:00:14 +08:00
|
|
|
case Stmt::IntegerLiteralClass:
|
|
|
|
K = CXCursor_IntegerLiteral;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::FloatingLiteralClass:
|
|
|
|
K = CXCursor_FloatingLiteral;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::ImaginaryLiteralClass:
|
|
|
|
K = CXCursor_ImaginaryLiteral;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::StringLiteralClass:
|
|
|
|
K = CXCursor_StringLiteral;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::CharacterLiteralClass:
|
|
|
|
K = CXCursor_CharacterLiteral;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::ParenExprClass:
|
|
|
|
K = CXCursor_ParenExpr;
|
|
|
|
break;
|
|
|
|
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-29 06:16:22 +08:00
|
|
|
case Stmt::UnaryOperatorClass:
|
2011-10-06 03:00:14 +08:00
|
|
|
K = CXCursor_UnaryOperator;
|
|
|
|
break;
|
2012-04-14 08:33:13 +08:00
|
|
|
|
2011-10-06 03:00:14 +08:00
|
|
|
case Stmt::CXXNoexceptExprClass:
|
|
|
|
K = CXCursor_UnaryExpr;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::ArraySubscriptExprClass:
|
|
|
|
K = CXCursor_ArraySubscriptExpr;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::BinaryOperatorClass:
|
|
|
|
K = CXCursor_BinaryOperator;
|
|
|
|
break;
|
|
|
|
|
2010-01-20 07:20:36 +08:00
|
|
|
case Stmt::CompoundAssignOperatorClass:
|
2011-10-06 03:00:14 +08:00
|
|
|
K = CXCursor_CompoundAssignOperator;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::ConditionalOperatorClass:
|
|
|
|
K = CXCursor_ConditionalOperator;
|
|
|
|
break;
|
|
|
|
|
2010-01-20 07:20:36 +08:00
|
|
|
case Stmt::CStyleCastExprClass:
|
2011-10-06 03:00:14 +08:00
|
|
|
K = CXCursor_CStyleCastExpr;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::CompoundLiteralExprClass:
|
|
|
|
K = CXCursor_CompoundLiteralExpr;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::InitListExprClass:
|
|
|
|
K = CXCursor_InitListExpr;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::AddrLabelExprClass:
|
|
|
|
K = CXCursor_AddrLabelExpr;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::StmtExprClass:
|
|
|
|
K = CXCursor_StmtExpr;
|
|
|
|
break;
|
|
|
|
|
2011-04-15 08:35:48 +08:00
|
|
|
case Stmt::GenericSelectionExprClass:
|
2011-10-06 03:00:14 +08:00
|
|
|
K = CXCursor_GenericSelectionExpr;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::GNUNullExprClass:
|
|
|
|
K = CXCursor_GNUNullExpr;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::CXXStaticCastExprClass:
|
|
|
|
K = CXCursor_CXXStaticCastExpr;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::CXXDynamicCastExprClass:
|
|
|
|
K = CXCursor_CXXDynamicCastExpr;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::CXXReinterpretCastExprClass:
|
|
|
|
K = CXCursor_CXXReinterpretCastExpr;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::CXXConstCastExprClass:
|
|
|
|
K = CXCursor_CXXConstCastExpr;
|
|
|
|
break;
|
|
|
|
|
2010-01-20 07:20:36 +08:00
|
|
|
case Stmt::CXXFunctionalCastExprClass:
|
2011-10-06 03:00:14 +08:00
|
|
|
K = CXCursor_CXXFunctionalCastExpr;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::CXXTypeidExprClass:
|
|
|
|
K = CXCursor_CXXTypeidExpr;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::CXXBoolLiteralExprClass:
|
|
|
|
K = CXCursor_CXXBoolLiteralExpr;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::CXXNullPtrLiteralExprClass:
|
|
|
|
K = CXCursor_CXXNullPtrLiteralExpr;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::CXXThisExprClass:
|
|
|
|
K = CXCursor_CXXThisExpr;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::CXXThrowExprClass:
|
|
|
|
K = CXCursor_CXXThrowExpr;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::CXXNewExprClass:
|
|
|
|
K = CXCursor_CXXNewExpr;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::CXXDeleteExprClass:
|
|
|
|
K = CXCursor_CXXDeleteExpr;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::ObjCStringLiteralClass:
|
|
|
|
K = CXCursor_ObjCStringLiteral;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::ObjCEncodeExprClass:
|
|
|
|
K = CXCursor_ObjCEncodeExpr;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::ObjCSelectorExprClass:
|
|
|
|
K = CXCursor_ObjCSelectorExpr;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::ObjCProtocolExprClass:
|
|
|
|
K = CXCursor_ObjCProtocolExpr;
|
|
|
|
break;
|
2012-03-07 04:06:06 +08:00
|
|
|
|
|
|
|
case Stmt::ObjCBoolLiteralExprClass:
|
|
|
|
K = CXCursor_ObjCBoolLiteralExpr;
|
|
|
|
break;
|
|
|
|
|
2011-06-16 07:02:42 +08:00
|
|
|
case Stmt::ObjCBridgedCastExprClass:
|
2011-10-06 03:00:14 +08:00
|
|
|
K = CXCursor_ObjCBridgedCastExpr;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::BlockExprClass:
|
|
|
|
K = CXCursor_BlockExpr;
|
|
|
|
break;
|
|
|
|
|
2011-01-04 01:17:50 +08:00
|
|
|
case Stmt::PackExpansionExprClass:
|
2011-10-06 03:00:14 +08:00
|
|
|
K = CXCursor_PackExpansionExpr;
|
|
|
|
break;
|
|
|
|
|
2011-01-05 01:33:58 +08:00
|
|
|
case Stmt::SizeOfPackExprClass:
|
2011-10-06 03:00:14 +08:00
|
|
|
K = CXCursor_SizeOfPackExpr;
|
2010-01-20 07:20:36 +08:00
|
|
|
break;
|
2011-10-06 03:00:14 +08:00
|
|
|
|
|
|
|
case Stmt::DeclRefExprClass:
|
|
|
|
case Stmt::DependentScopeDeclRefExprClass:
|
2011-07-15 13:09:51 +08:00
|
|
|
case Stmt::SubstNonTypeTemplateParmExprClass:
|
2011-01-15 09:15:58 +08:00
|
|
|
case Stmt::SubstNonTypeTemplateParmPackExprClass:
|
2011-10-06 03:00:14 +08:00
|
|
|
case Stmt::UnresolvedLookupExprClass:
|
2010-01-20 07:20:36 +08:00
|
|
|
K = CXCursor_DeclRefExpr;
|
|
|
|
break;
|
|
|
|
|
2011-10-06 03:00:14 +08:00
|
|
|
case Stmt::CXXDependentScopeMemberExprClass:
|
|
|
|
case Stmt::CXXPseudoDestructorExprClass:
|
2010-01-20 07:20:36 +08:00
|
|
|
case Stmt::MemberExprClass:
|
2011-10-06 03:00:14 +08:00
|
|
|
case Stmt::ObjCIsaExprClass:
|
2010-01-20 07:20:36 +08:00
|
|
|
case Stmt::ObjCIvarRefExprClass:
|
|
|
|
case Stmt::ObjCPropertyRefExprClass:
|
2011-10-06 03:00:14 +08:00
|
|
|
case Stmt::UnresolvedMemberExprClass:
|
2010-01-20 07:20:36 +08:00
|
|
|
K = CXCursor_MemberRefExpr;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::CallExprClass:
|
|
|
|
case Stmt::CXXOperatorCallExprClass:
|
|
|
|
case Stmt::CXXMemberCallExprClass:
|
2011-02-10 05:07:24 +08:00
|
|
|
case Stmt::CUDAKernelCallExprClass:
|
2010-01-20 07:20:36 +08:00
|
|
|
case Stmt::CXXConstructExprClass:
|
|
|
|
case Stmt::CXXTemporaryObjectExprClass:
|
2011-10-06 03:00:14 +08:00
|
|
|
case Stmt::CXXUnresolvedConstructExprClass:
|
2012-03-07 16:35:16 +08:00
|
|
|
case Stmt::UserDefinedLiteralClass:
|
2010-01-20 07:20:36 +08:00
|
|
|
K = CXCursor_CallExpr;
|
|
|
|
break;
|
|
|
|
|
2012-02-15 08:54:55 +08:00
|
|
|
case Stmt::LambdaExprClass:
|
|
|
|
K = CXCursor_LambdaExpr;
|
|
|
|
break;
|
|
|
|
|
2011-10-25 09:33:02 +08:00
|
|
|
case Stmt::ObjCMessageExprClass: {
|
2010-01-20 07:20:36 +08:00
|
|
|
K = CXCursor_ObjCMessageExpr;
|
2011-10-06 15:00:54 +08:00
|
|
|
int SelectorIdIndex = -1;
|
|
|
|
// Check if cursor points to a selector id.
|
|
|
|
if (RegionOfInterest.isValid() &&
|
|
|
|
RegionOfInterest.getBegin() == RegionOfInterest.getEnd()) {
|
|
|
|
SmallVector<SourceLocation, 16> SelLocs;
|
|
|
|
cast<ObjCMessageExpr>(S)->getSelectorLocs(SelLocs);
|
|
|
|
SmallVector<SourceLocation, 16>::iterator
|
|
|
|
I=std::find(SelLocs.begin(), SelLocs.end(),RegionOfInterest.getBegin());
|
|
|
|
if (I != SelLocs.end())
|
|
|
|
SelectorIdIndex = I - SelLocs.begin();
|
|
|
|
}
|
|
|
|
CXCursor C = { K, 0, { Parent, S, TU } };
|
|
|
|
return getSelectorIdentifierCursor(SelectorIdIndex, C);
|
2010-01-20 07:20:36 +08:00
|
|
|
}
|
2011-10-25 09:33:02 +08:00
|
|
|
|
|
|
|
case Stmt::MSDependentExistsStmtClass:
|
|
|
|
K = CXCursor_UnexposedStmt;
|
|
|
|
break;
|
|
|
|
}
|
2010-01-20 07:20:36 +08:00
|
|
|
|
2011-10-06 15:00:54 +08:00
|
|
|
CXCursor C = { K, 0, { Parent, S, TU } };
|
2010-01-20 07:20:36 +08:00
|
|
|
return C;
|
|
|
|
}
|
|
|
|
|
2010-01-16 22:00:32 +08:00
|
|
|
CXCursor cxcursor::MakeCursorObjCSuperClassRef(ObjCInterfaceDecl *Super,
|
2010-01-21 07:57:43 +08:00
|
|
|
SourceLocation Loc,
|
2010-11-16 16:15:36 +08:00
|
|
|
CXTranslationUnit TU) {
|
2010-01-25 08:40:30 +08:00
|
|
|
assert(Super && TU && "Invalid arguments!");
|
2010-01-16 22:00:32 +08:00
|
|
|
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
|
2011-10-06 15:00:54 +08:00
|
|
|
CXCursor C = { CXCursor_ObjCSuperClassRef, 0, { Super, RawLoc, TU } };
|
2010-01-16 22:00:32 +08:00
|
|
|
return C;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::pair<ObjCInterfaceDecl *, SourceLocation>
|
|
|
|
cxcursor::getCursorObjCSuperClassRef(CXCursor C) {
|
|
|
|
assert(C.kind == CXCursor_ObjCSuperClassRef);
|
|
|
|
return std::make_pair(static_cast<ObjCInterfaceDecl *>(C.data[0]),
|
|
|
|
SourceLocation::getFromRawEncoding(
|
|
|
|
reinterpret_cast<uintptr_t>(C.data[1])));
|
|
|
|
}
|
|
|
|
|
2011-10-18 03:48:19 +08:00
|
|
|
CXCursor cxcursor::MakeCursorObjCProtocolRef(const ObjCProtocolDecl *Proto,
|
2010-01-21 07:57:43 +08:00
|
|
|
SourceLocation Loc,
|
2010-11-16 16:15:36 +08:00
|
|
|
CXTranslationUnit TU) {
|
2011-10-18 03:48:19 +08:00
|
|
|
assert(Proto && TU && "Invalid arguments!");
|
2010-01-16 23:44:18 +08:00
|
|
|
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
|
2011-10-18 03:48:19 +08:00
|
|
|
CXCursor C = { CXCursor_ObjCProtocolRef, 0, { (void*)Proto, RawLoc, TU } };
|
2010-01-16 23:44:18 +08:00
|
|
|
return C;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::pair<ObjCProtocolDecl *, SourceLocation>
|
|
|
|
cxcursor::getCursorObjCProtocolRef(CXCursor C) {
|
|
|
|
assert(C.kind == CXCursor_ObjCProtocolRef);
|
|
|
|
return std::make_pair(static_cast<ObjCProtocolDecl *>(C.data[0]),
|
|
|
|
SourceLocation::getFromRawEncoding(
|
|
|
|
reinterpret_cast<uintptr_t>(C.data[1])));
|
|
|
|
}
|
|
|
|
|
2011-10-18 03:48:19 +08:00
|
|
|
CXCursor cxcursor::MakeCursorObjCClassRef(const ObjCInterfaceDecl *Class,
|
2010-01-21 07:57:43 +08:00
|
|
|
SourceLocation Loc,
|
2010-11-16 16:15:36 +08:00
|
|
|
CXTranslationUnit TU) {
|
2010-03-20 04:39:03 +08:00
|
|
|
// 'Class' can be null for invalid code.
|
|
|
|
if (!Class)
|
|
|
|
return MakeCXCursorInvalid(CXCursor_InvalidCode);
|
|
|
|
assert(TU && "Invalid arguments!");
|
2010-01-17 01:14:40 +08:00
|
|
|
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
|
2011-10-18 03:48:19 +08:00
|
|
|
CXCursor C = { CXCursor_ObjCClassRef, 0, { (void*)Class, RawLoc, TU } };
|
2010-01-17 01:14:40 +08:00
|
|
|
return C;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::pair<ObjCInterfaceDecl *, SourceLocation>
|
|
|
|
cxcursor::getCursorObjCClassRef(CXCursor C) {
|
|
|
|
assert(C.kind == CXCursor_ObjCClassRef);
|
|
|
|
return std::make_pair(static_cast<ObjCInterfaceDecl *>(C.data[0]),
|
|
|
|
SourceLocation::getFromRawEncoding(
|
|
|
|
reinterpret_cast<uintptr_t>(C.data[1])));
|
|
|
|
}
|
|
|
|
|
2011-10-18 03:48:19 +08:00
|
|
|
CXCursor cxcursor::MakeCursorTypeRef(const TypeDecl *Type, SourceLocation Loc,
|
2010-11-16 16:15:36 +08:00
|
|
|
CXTranslationUnit TU) {
|
2010-01-25 08:40:30 +08:00
|
|
|
assert(Type && TU && "Invalid arguments!");
|
2010-01-22 00:28:34 +08:00
|
|
|
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
|
2011-10-18 03:48:19 +08:00
|
|
|
CXCursor C = { CXCursor_TypeRef, 0, { (void*)Type, RawLoc, TU } };
|
2010-01-22 00:28:34 +08:00
|
|
|
return C;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::pair<TypeDecl *, SourceLocation>
|
|
|
|
cxcursor::getCursorTypeRef(CXCursor C) {
|
|
|
|
assert(C.kind == CXCursor_TypeRef);
|
|
|
|
return std::make_pair(static_cast<TypeDecl *>(C.data[0]),
|
|
|
|
SourceLocation::getFromRawEncoding(
|
|
|
|
reinterpret_cast<uintptr_t>(C.data[1])));
|
|
|
|
}
|
|
|
|
|
2011-11-18 08:26:51 +08:00
|
|
|
CXCursor cxcursor::MakeCursorTemplateRef(const TemplateDecl *Template,
|
2010-11-16 16:15:36 +08:00
|
|
|
SourceLocation Loc,
|
|
|
|
CXTranslationUnit TU) {
|
2010-09-01 04:37:03 +08:00
|
|
|
assert(Template && TU && "Invalid arguments!");
|
|
|
|
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
|
2011-11-18 08:26:51 +08:00
|
|
|
CXCursor C = { CXCursor_TemplateRef, 0, { (void*)Template, RawLoc, TU } };
|
2010-09-01 04:37:03 +08:00
|
|
|
return C;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::pair<TemplateDecl *, SourceLocation>
|
|
|
|
cxcursor::getCursorTemplateRef(CXCursor C) {
|
|
|
|
assert(C.kind == CXCursor_TemplateRef);
|
|
|
|
return std::make_pair(static_cast<TemplateDecl *>(C.data[0]),
|
|
|
|
SourceLocation::getFromRawEncoding(
|
|
|
|
reinterpret_cast<uintptr_t>(C.data[1])));
|
|
|
|
}
|
|
|
|
|
2011-11-18 08:26:51 +08:00
|
|
|
CXCursor cxcursor::MakeCursorNamespaceRef(const NamedDecl *NS,
|
|
|
|
SourceLocation Loc,
|
2010-11-16 16:15:36 +08:00
|
|
|
CXTranslationUnit TU) {
|
2010-09-01 07:48:11 +08:00
|
|
|
|
|
|
|
assert(NS && (isa<NamespaceDecl>(NS) || isa<NamespaceAliasDecl>(NS)) && TU &&
|
|
|
|
"Invalid arguments!");
|
|
|
|
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
|
2011-11-18 08:26:51 +08:00
|
|
|
CXCursor C = { CXCursor_NamespaceRef, 0, { (void*)NS, RawLoc, TU } };
|
2010-09-01 07:48:11 +08:00
|
|
|
return C;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::pair<NamedDecl *, SourceLocation>
|
|
|
|
cxcursor::getCursorNamespaceRef(CXCursor C) {
|
|
|
|
assert(C.kind == CXCursor_NamespaceRef);
|
|
|
|
return std::make_pair(static_cast<NamedDecl *>(C.data[0]),
|
|
|
|
SourceLocation::getFromRawEncoding(
|
|
|
|
reinterpret_cast<uintptr_t>(C.data[1])));
|
|
|
|
}
|
|
|
|
|
2012-02-15 08:54:55 +08:00
|
|
|
CXCursor cxcursor::MakeCursorVariableRef(const VarDecl *Var, SourceLocation Loc,
|
|
|
|
CXTranslationUnit TU) {
|
|
|
|
|
|
|
|
assert(Var && TU && "Invalid arguments!");
|
|
|
|
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
|
|
|
|
CXCursor C = { CXCursor_VariableRef, 0, { (void*)Var, RawLoc, TU } };
|
|
|
|
return C;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::pair<VarDecl *, SourceLocation>
|
|
|
|
cxcursor::getCursorVariableRef(CXCursor C) {
|
|
|
|
assert(C.kind == CXCursor_VariableRef);
|
|
|
|
return std::make_pair(static_cast<VarDecl *>(C.data[0]),
|
|
|
|
SourceLocation::getFromRawEncoding(
|
|
|
|
reinterpret_cast<uintptr_t>(C.data[1])));
|
|
|
|
}
|
|
|
|
|
2011-11-18 08:26:51 +08:00
|
|
|
CXCursor cxcursor::MakeCursorMemberRef(const FieldDecl *Field, SourceLocation Loc,
|
2010-11-16 16:15:36 +08:00
|
|
|
CXTranslationUnit TU) {
|
2010-09-10 05:42:20 +08:00
|
|
|
|
|
|
|
assert(Field && TU && "Invalid arguments!");
|
|
|
|
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
|
2011-11-18 08:26:51 +08:00
|
|
|
CXCursor C = { CXCursor_MemberRef, 0, { (void*)Field, RawLoc, TU } };
|
2010-09-10 05:42:20 +08:00
|
|
|
return C;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::pair<FieldDecl *, SourceLocation>
|
|
|
|
cxcursor::getCursorMemberRef(CXCursor C) {
|
|
|
|
assert(C.kind == CXCursor_MemberRef);
|
|
|
|
return std::make_pair(static_cast<FieldDecl *>(C.data[0]),
|
|
|
|
SourceLocation::getFromRawEncoding(
|
|
|
|
reinterpret_cast<uintptr_t>(C.data[1])));
|
|
|
|
}
|
|
|
|
|
2011-11-22 15:24:51 +08:00
|
|
|
CXCursor cxcursor::MakeCursorCXXBaseSpecifier(const CXXBaseSpecifier *B,
|
2010-11-16 16:15:36 +08:00
|
|
|
CXTranslationUnit TU){
|
2011-11-22 15:24:51 +08:00
|
|
|
CXCursor C = { CXCursor_CXXBaseSpecifier, 0, { (void*)B, 0, TU } };
|
2010-08-28 05:34:58 +08:00
|
|
|
return C;
|
|
|
|
}
|
|
|
|
|
|
|
|
CXXBaseSpecifier *cxcursor::getCursorCXXBaseSpecifier(CXCursor C) {
|
|
|
|
assert(C.kind == CXCursor_CXXBaseSpecifier);
|
|
|
|
return static_cast<CXXBaseSpecifier*>(C.data[0]);
|
|
|
|
}
|
|
|
|
|
2010-03-18 08:42:48 +08:00
|
|
|
CXCursor cxcursor::MakePreprocessingDirectiveCursor(SourceRange Range,
|
2010-11-16 16:15:36 +08:00
|
|
|
CXTranslationUnit TU) {
|
2011-10-06 15:00:54 +08:00
|
|
|
CXCursor C = { CXCursor_PreprocessingDirective, 0,
|
2010-03-18 08:42:48 +08:00
|
|
|
{ reinterpret_cast<void *>(Range.getBegin().getRawEncoding()),
|
|
|
|
reinterpret_cast<void *>(Range.getEnd().getRawEncoding()),
|
|
|
|
TU }
|
|
|
|
};
|
|
|
|
return C;
|
|
|
|
}
|
|
|
|
|
|
|
|
SourceRange cxcursor::getCursorPreprocessingDirective(CXCursor C) {
|
|
|
|
assert(C.kind == CXCursor_PreprocessingDirective);
|
2011-09-26 16:01:41 +08:00
|
|
|
SourceRange Range = SourceRange(SourceLocation::getFromRawEncoding(
|
2010-03-18 23:23:44 +08:00
|
|
|
reinterpret_cast<uintptr_t> (C.data[0])),
|
|
|
|
SourceLocation::getFromRawEncoding(
|
|
|
|
reinterpret_cast<uintptr_t> (C.data[1])));
|
2011-09-26 16:01:41 +08:00
|
|
|
ASTUnit *TU = getCursorASTUnit(C);
|
|
|
|
return TU->mapRangeFromPreamble(Range);
|
2010-03-18 23:23:44 +08:00
|
|
|
}
|
|
|
|
|
2010-11-16 16:15:36 +08:00
|
|
|
CXCursor cxcursor::MakeMacroDefinitionCursor(MacroDefinition *MI,
|
|
|
|
CXTranslationUnit TU) {
|
2011-10-06 15:00:54 +08:00
|
|
|
CXCursor C = { CXCursor_MacroDefinition, 0, { MI, 0, TU } };
|
2010-03-19 02:04:21 +08:00
|
|
|
return C;
|
|
|
|
}
|
|
|
|
|
|
|
|
MacroDefinition *cxcursor::getCursorMacroDefinition(CXCursor C) {
|
|
|
|
assert(C.kind == CXCursor_MacroDefinition);
|
|
|
|
return static_cast<MacroDefinition *>(C.data[0]);
|
|
|
|
}
|
|
|
|
|
2011-07-14 16:20:46 +08:00
|
|
|
CXCursor cxcursor::MakeMacroExpansionCursor(MacroExpansion *MI,
|
|
|
|
CXTranslationUnit TU) {
|
2011-10-06 15:00:54 +08:00
|
|
|
CXCursor C = { CXCursor_MacroExpansion, 0, { MI, 0, TU } };
|
2010-03-18 23:23:44 +08:00
|
|
|
return C;
|
|
|
|
}
|
|
|
|
|
2011-07-14 16:20:46 +08:00
|
|
|
MacroExpansion *cxcursor::getCursorMacroExpansion(CXCursor C) {
|
2011-07-14 16:41:15 +08:00
|
|
|
assert(C.kind == CXCursor_MacroExpansion);
|
2011-07-14 16:20:46 +08:00
|
|
|
return static_cast<MacroExpansion *>(C.data[0]);
|
2010-03-18 08:42:48 +08:00
|
|
|
}
|
|
|
|
|
2010-10-21 06:00:55 +08:00
|
|
|
CXCursor cxcursor::MakeInclusionDirectiveCursor(InclusionDirective *ID,
|
2010-11-16 16:15:36 +08:00
|
|
|
CXTranslationUnit TU) {
|
2011-10-06 15:00:54 +08:00
|
|
|
CXCursor C = { CXCursor_InclusionDirective, 0, { ID, 0, TU } };
|
2010-10-21 06:00:55 +08:00
|
|
|
return C;
|
|
|
|
}
|
|
|
|
|
|
|
|
InclusionDirective *cxcursor::getCursorInclusionDirective(CXCursor C) {
|
|
|
|
assert(C.kind == CXCursor_InclusionDirective);
|
|
|
|
return static_cast<InclusionDirective *>(C.data[0]);
|
|
|
|
}
|
|
|
|
|
2010-09-10 08:22:18 +08:00
|
|
|
CXCursor cxcursor::MakeCursorLabelRef(LabelStmt *Label, SourceLocation Loc,
|
2010-11-16 16:15:36 +08:00
|
|
|
CXTranslationUnit TU) {
|
2010-09-10 08:22:18 +08:00
|
|
|
|
|
|
|
assert(Label && TU && "Invalid arguments!");
|
|
|
|
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
|
2011-10-06 15:00:54 +08:00
|
|
|
CXCursor C = { CXCursor_LabelRef, 0, { Label, RawLoc, TU } };
|
2010-09-10 08:22:18 +08:00
|
|
|
return C;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::pair<LabelStmt*, SourceLocation>
|
|
|
|
cxcursor::getCursorLabelRef(CXCursor C) {
|
|
|
|
assert(C.kind == CXCursor_LabelRef);
|
|
|
|
return std::make_pair(static_cast<LabelStmt *>(C.data[0]),
|
|
|
|
SourceLocation::getFromRawEncoding(
|
|
|
|
reinterpret_cast<uintptr_t>(C.data[1])));
|
|
|
|
}
|
|
|
|
|
2010-09-14 06:52:57 +08:00
|
|
|
CXCursor cxcursor::MakeCursorOverloadedDeclRef(OverloadExpr *E,
|
2010-11-16 16:15:36 +08:00
|
|
|
CXTranslationUnit TU) {
|
2010-09-14 06:52:57 +08:00
|
|
|
assert(E && TU && "Invalid arguments!");
|
|
|
|
OverloadedDeclRefStorage Storage(E);
|
|
|
|
void *RawLoc = reinterpret_cast<void *>(E->getNameLoc().getRawEncoding());
|
|
|
|
CXCursor C = {
|
2011-10-06 15:00:54 +08:00
|
|
|
CXCursor_OverloadedDeclRef, 0,
|
2010-09-14 06:52:57 +08:00
|
|
|
{ Storage.getOpaqueValue(), RawLoc, TU }
|
|
|
|
};
|
|
|
|
return C;
|
|
|
|
}
|
|
|
|
|
|
|
|
CXCursor cxcursor::MakeCursorOverloadedDeclRef(Decl *D,
|
|
|
|
SourceLocation Loc,
|
2010-11-16 16:15:36 +08:00
|
|
|
CXTranslationUnit TU) {
|
2010-09-14 06:52:57 +08:00
|
|
|
assert(D && TU && "Invalid arguments!");
|
|
|
|
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
|
|
|
|
OverloadedDeclRefStorage Storage(D);
|
|
|
|
CXCursor C = {
|
2011-10-06 15:00:54 +08:00
|
|
|
CXCursor_OverloadedDeclRef, 0,
|
2010-09-14 06:52:57 +08:00
|
|
|
{ Storage.getOpaqueValue(), RawLoc, TU }
|
|
|
|
};
|
|
|
|
return C;
|
|
|
|
}
|
|
|
|
|
|
|
|
CXCursor cxcursor::MakeCursorOverloadedDeclRef(TemplateName Name,
|
|
|
|
SourceLocation Loc,
|
2010-11-16 16:15:36 +08:00
|
|
|
CXTranslationUnit TU) {
|
2010-09-14 06:52:57 +08:00
|
|
|
assert(Name.getAsOverloadedTemplate() && TU && "Invalid arguments!");
|
|
|
|
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
|
|
|
|
OverloadedDeclRefStorage Storage(Name.getAsOverloadedTemplate());
|
|
|
|
CXCursor C = {
|
2011-10-06 15:00:54 +08:00
|
|
|
CXCursor_OverloadedDeclRef, 0,
|
2010-09-14 06:52:57 +08:00
|
|
|
{ Storage.getOpaqueValue(), RawLoc, TU }
|
|
|
|
};
|
|
|
|
return C;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::pair<cxcursor::OverloadedDeclRefStorage, SourceLocation>
|
|
|
|
cxcursor::getCursorOverloadedDeclRef(CXCursor C) {
|
|
|
|
assert(C.kind == CXCursor_OverloadedDeclRef);
|
|
|
|
return std::make_pair(OverloadedDeclRefStorage::getFromOpaqueValue(C.data[0]),
|
|
|
|
SourceLocation::getFromRawEncoding(
|
|
|
|
reinterpret_cast<uintptr_t>(C.data[1])));
|
|
|
|
}
|
|
|
|
|
2010-01-16 05:56:13 +08:00
|
|
|
Decl *cxcursor::getCursorDecl(CXCursor Cursor) {
|
|
|
|
return (Decl *)Cursor.data[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
Expr *cxcursor::getCursorExpr(CXCursor Cursor) {
|
|
|
|
return dyn_cast_or_null<Expr>(getCursorStmt(Cursor));
|
|
|
|
}
|
|
|
|
|
|
|
|
Stmt *cxcursor::getCursorStmt(CXCursor Cursor) {
|
2010-01-16 23:44:18 +08:00
|
|
|
if (Cursor.kind == CXCursor_ObjCSuperClassRef ||
|
2010-01-17 01:14:40 +08:00
|
|
|
Cursor.kind == CXCursor_ObjCProtocolRef ||
|
|
|
|
Cursor.kind == CXCursor_ObjCClassRef)
|
2010-01-16 22:00:32 +08:00
|
|
|
return 0;
|
|
|
|
|
2010-01-16 05:56:13 +08:00
|
|
|
return (Stmt *)Cursor.data[1];
|
|
|
|
}
|
|
|
|
|
2010-08-26 09:42:22 +08:00
|
|
|
Attr *cxcursor::getCursorAttr(CXCursor Cursor) {
|
|
|
|
return (Attr *)Cursor.data[1];
|
|
|
|
}
|
|
|
|
|
2011-06-30 06:20:07 +08:00
|
|
|
Decl *cxcursor::getCursorParentDecl(CXCursor Cursor) {
|
|
|
|
return (Decl *)Cursor.data[0];
|
|
|
|
}
|
|
|
|
|
2010-01-19 07:41:10 +08:00
|
|
|
ASTContext &cxcursor::getCursorContext(CXCursor Cursor) {
|
2010-01-21 07:57:43 +08:00
|
|
|
return getCursorASTUnit(Cursor)->getASTContext();
|
|
|
|
}
|
2010-01-20 07:20:36 +08:00
|
|
|
|
2010-01-21 07:57:43 +08:00
|
|
|
ASTUnit *cxcursor::getCursorASTUnit(CXCursor Cursor) {
|
2011-12-09 08:17:49 +08:00
|
|
|
CXTranslationUnit TU = static_cast<CXTranslationUnit>(Cursor.data[2]);
|
|
|
|
if (!TU)
|
|
|
|
return 0;
|
|
|
|
return static_cast<ASTUnit *>(TU->TUData);
|
2010-11-16 16:15:36 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
CXTranslationUnit cxcursor::getCursorTU(CXCursor Cursor) {
|
|
|
|
return static_cast<CXTranslationUnit>(Cursor.data[2]);
|
2010-01-16 05:56:13 +08:00
|
|
|
}
|
|
|
|
|
2012-04-11 05:01:03 +08:00
|
|
|
static void CollectOverriddenMethodsRecurse(CXTranslationUnit TU,
|
|
|
|
ObjCContainerDecl *Container,
|
2011-10-06 15:00:46 +08:00
|
|
|
ObjCMethodDecl *Method,
|
2012-04-11 05:01:03 +08:00
|
|
|
SmallVectorImpl<CXCursor> &Methods,
|
|
|
|
bool MovedToSuper) {
|
2011-10-06 15:00:46 +08:00
|
|
|
if (!Container)
|
|
|
|
return;
|
|
|
|
|
[libclang] Enhance clang_getOverriddenCursors.
Basically the current design is:
-for an implementation method, show as overridden the interface method.
This is not useful, and is inconsistent with the C++ side
-for an interface method, show as overridden the protocols methods (this is desirable)
and the methods from the categories; methods from categories are not useful
since they are considered the same method (same USR).
-If there is a protocol method or category method reported, it does not check the
super class for overridden methods. This is really problematic since
overridden methods from super class is what we want to give back.
Change clang_getOverriddenCursors to show as overridden any method in the class's
base class, its protocols, or its categories' protocols, that has the same
selector and is of the same kind (class or instance).
If no such method exists, the search continues to the class's superclass,
its protocols, and its categories, and so on. A method from an Objective-C
implementation is considered to override the same methods as its
corresponding method in the interface.
rdar://10967206
llvm-svn: 152270
2012-03-08 08:20:03 +08:00
|
|
|
// In categories look for overriden methods from protocols. A method from
|
|
|
|
// category is not "overriden" since it is considered as the "same" method
|
|
|
|
// (same USR) as the one from the interface.
|
|
|
|
if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
|
2012-04-11 05:01:03 +08:00
|
|
|
// Check whether we have a matching method at this category but only if we
|
|
|
|
// are at the super class level.
|
|
|
|
if (MovedToSuper)
|
|
|
|
if (ObjCMethodDecl *
|
|
|
|
Overridden = Container->getMethod(Method->getSelector(),
|
|
|
|
Method->isInstanceMethod()))
|
|
|
|
if (Method != Overridden) {
|
|
|
|
// We found an override at this category; there is no need to look
|
|
|
|
// into its protocols.
|
|
|
|
Methods.push_back(MakeCXCursor(Overridden, TU));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
[libclang] Enhance clang_getOverriddenCursors.
Basically the current design is:
-for an implementation method, show as overridden the interface method.
This is not useful, and is inconsistent with the C++ side
-for an interface method, show as overridden the protocols methods (this is desirable)
and the methods from the categories; methods from categories are not useful
since they are considered the same method (same USR).
-If there is a protocol method or category method reported, it does not check the
super class for overridden methods. This is really problematic since
overridden methods from super class is what we want to give back.
Change clang_getOverriddenCursors to show as overridden any method in the class's
base class, its protocols, or its categories' protocols, that has the same
selector and is of the same kind (class or instance).
If no such method exists, the search continues to the class's superclass,
its protocols, and its categories, and so on. A method from an Objective-C
implementation is considered to override the same methods as its
corresponding method in the interface.
rdar://10967206
llvm-svn: 152270
2012-03-08 08:20:03 +08:00
|
|
|
for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
|
|
|
|
PEnd = Category->protocol_end();
|
|
|
|
P != PEnd; ++P)
|
2012-04-11 05:01:03 +08:00
|
|
|
CollectOverriddenMethodsRecurse(TU, *P, Method, Methods, MovedToSuper);
|
[libclang] Enhance clang_getOverriddenCursors.
Basically the current design is:
-for an implementation method, show as overridden the interface method.
This is not useful, and is inconsistent with the C++ side
-for an interface method, show as overridden the protocols methods (this is desirable)
and the methods from the categories; methods from categories are not useful
since they are considered the same method (same USR).
-If there is a protocol method or category method reported, it does not check the
super class for overridden methods. This is really problematic since
overridden methods from super class is what we want to give back.
Change clang_getOverriddenCursors to show as overridden any method in the class's
base class, its protocols, or its categories' protocols, that has the same
selector and is of the same kind (class or instance).
If no such method exists, the search continues to the class's superclass,
its protocols, and its categories, and so on. A method from an Objective-C
implementation is considered to override the same methods as its
corresponding method in the interface.
rdar://10967206
llvm-svn: 152270
2012-03-08 08:20:03 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-10-06 15:00:46 +08:00
|
|
|
// Check whether we have a matching method at this level.
|
|
|
|
if (ObjCMethodDecl *Overridden = Container->getMethod(Method->getSelector(),
|
|
|
|
Method->isInstanceMethod()))
|
|
|
|
if (Method != Overridden) {
|
|
|
|
// We found an override at this level; there is no need to look
|
|
|
|
// into other protocols or categories.
|
|
|
|
Methods.push_back(MakeCXCursor(Overridden, TU));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
|
|
|
|
for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
|
|
|
|
PEnd = Protocol->protocol_end();
|
|
|
|
P != PEnd; ++P)
|
2012-04-11 05:01:03 +08:00
|
|
|
CollectOverriddenMethodsRecurse(TU, *P, Method, Methods, MovedToSuper);
|
2011-10-06 15:00:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
|
|
|
|
for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(),
|
|
|
|
PEnd = Interface->protocol_end();
|
|
|
|
P != PEnd; ++P)
|
2012-04-11 05:01:03 +08:00
|
|
|
CollectOverriddenMethodsRecurse(TU, *P, Method, Methods, MovedToSuper);
|
2011-10-06 15:00:46 +08:00
|
|
|
|
|
|
|
for (ObjCCategoryDecl *Category = Interface->getCategoryList();
|
|
|
|
Category; Category = Category->getNextClassCategory())
|
2012-04-11 05:01:03 +08:00
|
|
|
CollectOverriddenMethodsRecurse(TU, Category, Method, Methods,
|
|
|
|
MovedToSuper);
|
2011-10-06 15:00:46 +08:00
|
|
|
|
[libclang] Enhance clang_getOverriddenCursors.
Basically the current design is:
-for an implementation method, show as overridden the interface method.
This is not useful, and is inconsistent with the C++ side
-for an interface method, show as overridden the protocols methods (this is desirable)
and the methods from the categories; methods from categories are not useful
since they are considered the same method (same USR).
-If there is a protocol method or category method reported, it does not check the
super class for overridden methods. This is really problematic since
overridden methods from super class is what we want to give back.
Change clang_getOverriddenCursors to show as overridden any method in the class's
base class, its protocols, or its categories' protocols, that has the same
selector and is of the same kind (class or instance).
If no such method exists, the search continues to the class's superclass,
its protocols, and its categories, and so on. A method from an Objective-C
implementation is considered to override the same methods as its
corresponding method in the interface.
rdar://10967206
llvm-svn: 152270
2012-03-08 08:20:03 +08:00
|
|
|
if (ObjCInterfaceDecl *Super = Interface->getSuperClass())
|
2012-04-11 05:01:03 +08:00
|
|
|
return CollectOverriddenMethodsRecurse(TU, Super, Method, Methods,
|
|
|
|
/*MovedToSuper=*/true);
|
2011-10-06 15:00:46 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-04-11 05:01:03 +08:00
|
|
|
static inline void CollectOverriddenMethods(CXTranslationUnit TU,
|
|
|
|
ObjCContainerDecl *Container,
|
|
|
|
ObjCMethodDecl *Method,
|
|
|
|
SmallVectorImpl<CXCursor> &Methods) {
|
|
|
|
CollectOverriddenMethodsRecurse(TU, Container, Method, Methods,
|
|
|
|
/*MovedToSuper=*/false);
|
|
|
|
}
|
|
|
|
|
2012-05-10 00:12:57 +08:00
|
|
|
static void collectOverriddenMethodsSlow(CXTranslationUnit TU,
|
|
|
|
ObjCMethodDecl *Method,
|
|
|
|
SmallVectorImpl<CXCursor> &overridden) {
|
|
|
|
assert(Method->isOverriding());
|
2011-10-06 15:00:46 +08:00
|
|
|
|
[libclang] Enhance clang_getOverriddenCursors.
Basically the current design is:
-for an implementation method, show as overridden the interface method.
This is not useful, and is inconsistent with the C++ side
-for an interface method, show as overridden the protocols methods (this is desirable)
and the methods from the categories; methods from categories are not useful
since they are considered the same method (same USR).
-If there is a protocol method or category method reported, it does not check the
super class for overridden methods. This is really problematic since
overridden methods from super class is what we want to give back.
Change clang_getOverriddenCursors to show as overridden any method in the class's
base class, its protocols, or its categories' protocols, that has the same
selector and is of the same kind (class or instance).
If no such method exists, the search continues to the class's superclass,
its protocols, and its categories, and so on. A method from an Objective-C
implementation is considered to override the same methods as its
corresponding method in the interface.
rdar://10967206
llvm-svn: 152270
2012-03-08 08:20:03 +08:00
|
|
|
if (ObjCProtocolDecl *
|
|
|
|
ProtD = dyn_cast<ObjCProtocolDecl>(Method->getDeclContext())) {
|
|
|
|
CollectOverriddenMethods(TU, ProtD, Method, overridden);
|
|
|
|
|
|
|
|
} else if (ObjCImplDecl *
|
|
|
|
IMD = dyn_cast<ObjCImplDecl>(Method->getDeclContext())) {
|
|
|
|
ObjCInterfaceDecl *ID = IMD->getClassInterface();
|
|
|
|
if (!ID)
|
|
|
|
return;
|
|
|
|
// Start searching for overridden methods using the method from the
|
|
|
|
// interface as starting point.
|
|
|
|
if (ObjCMethodDecl *IFaceMeth = ID->getMethod(Method->getSelector(),
|
|
|
|
Method->isInstanceMethod()))
|
|
|
|
Method = IFaceMeth;
|
|
|
|
CollectOverriddenMethods(TU, ID, Method, overridden);
|
|
|
|
|
|
|
|
} else if (ObjCCategoryDecl *
|
|
|
|
CatD = dyn_cast<ObjCCategoryDecl>(Method->getDeclContext())) {
|
|
|
|
ObjCInterfaceDecl *ID = CatD->getClassInterface();
|
|
|
|
if (!ID)
|
|
|
|
return;
|
|
|
|
// Start searching for overridden methods using the method from the
|
|
|
|
// interface as starting point.
|
|
|
|
if (ObjCMethodDecl *IFaceMeth = ID->getMethod(Method->getSelector(),
|
|
|
|
Method->isInstanceMethod()))
|
|
|
|
Method = IFaceMeth;
|
|
|
|
CollectOverriddenMethods(TU, ID, Method, overridden);
|
|
|
|
|
|
|
|
} else {
|
2012-04-11 05:01:03 +08:00
|
|
|
CollectOverriddenMethods(TU,
|
|
|
|
dyn_cast_or_null<ObjCContainerDecl>(Method->getDeclContext()),
|
|
|
|
Method, overridden);
|
[libclang] Enhance clang_getOverriddenCursors.
Basically the current design is:
-for an implementation method, show as overridden the interface method.
This is not useful, and is inconsistent with the C++ side
-for an interface method, show as overridden the protocols methods (this is desirable)
and the methods from the categories; methods from categories are not useful
since they are considered the same method (same USR).
-If there is a protocol method or category method reported, it does not check the
super class for overridden methods. This is really problematic since
overridden methods from super class is what we want to give back.
Change clang_getOverriddenCursors to show as overridden any method in the class's
base class, its protocols, or its categories' protocols, that has the same
selector and is of the same kind (class or instance).
If no such method exists, the search continues to the class's superclass,
its protocols, and its categories, and so on. A method from an Objective-C
implementation is considered to override the same methods as its
corresponding method in the interface.
rdar://10967206
llvm-svn: 152270
2012-03-08 08:20:03 +08:00
|
|
|
}
|
2011-10-06 15:00:46 +08:00
|
|
|
}
|
|
|
|
|
2012-05-10 00:12:57 +08:00
|
|
|
static void collectOnCategoriesAfterLocation(SourceLocation Loc,
|
|
|
|
ObjCInterfaceDecl *Class,
|
|
|
|
CXTranslationUnit TU,
|
|
|
|
ObjCMethodDecl *Method,
|
|
|
|
SmallVectorImpl<CXCursor> &Methods) {
|
|
|
|
if (!Class)
|
|
|
|
return;
|
|
|
|
|
|
|
|
SourceManager &SM = static_cast<ASTUnit *>(TU->TUData)->getSourceManager();
|
|
|
|
for (ObjCCategoryDecl *Category = Class->getCategoryList();
|
|
|
|
Category; Category = Category->getNextClassCategory())
|
|
|
|
if (SM.isBeforeInTranslationUnit(Loc, Category->getLocation()))
|
|
|
|
CollectOverriddenMethodsRecurse(TU, Category, Method, Methods, true);
|
|
|
|
|
|
|
|
collectOnCategoriesAfterLocation(Loc, Class->getSuperClass(), TU,
|
|
|
|
Method, Methods);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Faster collection that is enabled when ObjCMethodDecl::isOverriding()
|
|
|
|
/// returns false.
|
|
|
|
/// You'd think that in that case there are no overrides but categories can
|
|
|
|
/// "introduce" new overridden methods that are missed by Sema because the
|
|
|
|
/// overrides lookup that it does for methods, inside implementations, will
|
|
|
|
/// stop at the interface level (if there is a method there) and not look
|
|
|
|
/// further in super classes.
|
|
|
|
static void collectOverriddenMethodsFast(CXTranslationUnit TU,
|
|
|
|
ObjCMethodDecl *Method,
|
|
|
|
SmallVectorImpl<CXCursor> &Methods) {
|
|
|
|
assert(!Method->isOverriding());
|
|
|
|
|
|
|
|
ObjCContainerDecl *ContD = cast<ObjCContainerDecl>(Method->getDeclContext());
|
|
|
|
if (isa<ObjCInterfaceDecl>(ContD) || isa<ObjCProtocolDecl>(ContD))
|
|
|
|
return;
|
|
|
|
ObjCInterfaceDecl *Class = Method->getClassInterface();
|
|
|
|
if (!Class)
|
|
|
|
return;
|
|
|
|
|
|
|
|
collectOnCategoriesAfterLocation(Class->getLocation(), Class->getSuperClass(),
|
|
|
|
TU, Method, Methods);
|
|
|
|
}
|
|
|
|
|
|
|
|
void cxcursor::getOverriddenCursors(CXCursor cursor,
|
|
|
|
SmallVectorImpl<CXCursor> &overridden) {
|
|
|
|
assert(clang_isDeclaration(cursor.kind));
|
|
|
|
Decl *D = getCursorDecl(cursor);
|
|
|
|
if (!D)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Handle C++ member functions.
|
|
|
|
CXTranslationUnit TU = getCursorTU(cursor);
|
|
|
|
if (CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
|
|
|
|
for (CXXMethodDecl::method_iterator
|
|
|
|
M = CXXMethod->begin_overridden_methods(),
|
|
|
|
MEnd = CXXMethod->end_overridden_methods();
|
|
|
|
M != MEnd; ++M)
|
|
|
|
overridden.push_back(MakeCXCursor(const_cast<CXXMethodDecl*>(*M), TU));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D);
|
|
|
|
if (!Method)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (Method->isRedeclaration()) {
|
|
|
|
Method = cast<ObjCContainerDecl>(Method->getDeclContext())->
|
|
|
|
getMethod(Method->getSelector(), Method->isInstanceMethod());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!Method->isOverriding()) {
|
|
|
|
collectOverriddenMethodsFast(TU, Method, overridden);
|
|
|
|
} else {
|
|
|
|
collectOverriddenMethodsSlow(TU, Method, overridden);
|
|
|
|
assert(!overridden.empty() &&
|
|
|
|
"ObjCMethodDecl's overriding bit is not as expected");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-10-06 15:00:54 +08:00
|
|
|
std::pair<int, SourceLocation>
|
|
|
|
cxcursor::getSelectorIdentifierIndexAndLoc(CXCursor cursor) {
|
|
|
|
if (cursor.kind == CXCursor_ObjCMessageExpr) {
|
|
|
|
if (cursor.xdata != -1)
|
|
|
|
return std::make_pair(cursor.xdata,
|
|
|
|
cast<ObjCMessageExpr>(getCursorExpr(cursor))
|
|
|
|
->getSelectorLoc(cursor.xdata));
|
|
|
|
} else if (cursor.kind == CXCursor_ObjCClassMethodDecl ||
|
|
|
|
cursor.kind == CXCursor_ObjCInstanceMethodDecl) {
|
|
|
|
if (cursor.xdata != -1)
|
|
|
|
return std::make_pair(cursor.xdata,
|
|
|
|
cast<ObjCMethodDecl>(getCursorDecl(cursor))
|
|
|
|
->getSelectorLoc(cursor.xdata));
|
|
|
|
}
|
|
|
|
|
|
|
|
return std::make_pair(-1, SourceLocation());
|
|
|
|
}
|
|
|
|
|
|
|
|
CXCursor cxcursor::getSelectorIdentifierCursor(int SelIdx, CXCursor cursor) {
|
|
|
|
CXCursor newCursor = cursor;
|
|
|
|
|
|
|
|
if (cursor.kind == CXCursor_ObjCMessageExpr) {
|
|
|
|
if (SelIdx == -1 ||
|
|
|
|
unsigned(SelIdx) >= cast<ObjCMessageExpr>(getCursorExpr(cursor))
|
|
|
|
->getNumSelectorLocs())
|
|
|
|
newCursor.xdata = -1;
|
|
|
|
else
|
|
|
|
newCursor.xdata = SelIdx;
|
|
|
|
} else if (cursor.kind == CXCursor_ObjCClassMethodDecl ||
|
|
|
|
cursor.kind == CXCursor_ObjCInstanceMethodDecl) {
|
|
|
|
if (SelIdx == -1 ||
|
|
|
|
unsigned(SelIdx) >= cast<ObjCMethodDecl>(getCursorDecl(cursor))
|
|
|
|
->getNumSelectorLocs())
|
|
|
|
newCursor.xdata = -1;
|
|
|
|
else
|
|
|
|
newCursor.xdata = SelIdx;
|
|
|
|
}
|
|
|
|
|
|
|
|
return newCursor;
|
|
|
|
}
|
|
|
|
|
|
|
|
CXCursor cxcursor::getTypeRefCursor(CXCursor cursor) {
|
|
|
|
if (cursor.kind != CXCursor_CallExpr)
|
|
|
|
return cursor;
|
|
|
|
|
|
|
|
if (cursor.xdata == 0)
|
|
|
|
return cursor;
|
|
|
|
|
|
|
|
Expr *E = getCursorExpr(cursor);
|
|
|
|
TypeSourceInfo *Type = 0;
|
|
|
|
if (CXXUnresolvedConstructExpr *
|
|
|
|
UnCtor = dyn_cast<CXXUnresolvedConstructExpr>(E)) {
|
|
|
|
Type = UnCtor->getTypeSourceInfo();
|
|
|
|
} else if (CXXTemporaryObjectExpr *Tmp = dyn_cast<CXXTemporaryObjectExpr>(E)){
|
|
|
|
Type = Tmp->getTypeSourceInfo();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!Type)
|
|
|
|
return cursor;
|
|
|
|
|
|
|
|
CXTranslationUnit TU = getCursorTU(cursor);
|
|
|
|
QualType Ty = Type->getType();
|
|
|
|
TypeLoc TL = Type->getTypeLoc();
|
|
|
|
SourceLocation Loc = TL.getBeginLoc();
|
|
|
|
|
|
|
|
if (const ElaboratedType *ElabT = Ty->getAs<ElaboratedType>()) {
|
|
|
|
Ty = ElabT->getNamedType();
|
|
|
|
ElaboratedTypeLoc ElabTL = cast<ElaboratedTypeLoc>(TL);
|
|
|
|
Loc = ElabTL.getNamedTypeLoc().getBeginLoc();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (const TypedefType *Typedef = Ty->getAs<TypedefType>())
|
|
|
|
return MakeCursorTypeRef(Typedef->getDecl(), Loc, TU);
|
|
|
|
if (const TagType *Tag = Ty->getAs<TagType>())
|
|
|
|
return MakeCursorTypeRef(Tag->getDecl(), Loc, TU);
|
|
|
|
if (const TemplateTypeParmType *TemplP = Ty->getAs<TemplateTypeParmType>())
|
|
|
|
return MakeCursorTypeRef(TemplP->getDecl(), Loc, TU);
|
|
|
|
|
|
|
|
return cursor;
|
|
|
|
}
|
|
|
|
|
2010-01-16 05:56:13 +08:00
|
|
|
bool cxcursor::operator==(CXCursor X, CXCursor Y) {
|
|
|
|
return X.kind == Y.kind && X.data[0] == Y.data[0] && X.data[1] == Y.data[1] &&
|
|
|
|
X.data[2] == Y.data[2];
|
2010-01-16 22:00:32 +08:00
|
|
|
}
|
2010-11-02 07:26:51 +08:00
|
|
|
|
|
|
|
// FIXME: Remove once we can model DeclGroups and their appropriate ranges
|
|
|
|
// properly in the ASTs.
|
|
|
|
bool cxcursor::isFirstInDeclGroup(CXCursor C) {
|
|
|
|
assert(clang_isDeclaration(C.kind));
|
|
|
|
return ((uintptr_t) (C.data[1])) != 0;
|
|
|
|
}
|
|
|
|
|
2011-09-27 08:30:30 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// libclang CXCursor APIs
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2011-09-27 12:14:36 +08:00
|
|
|
extern "C" {
|
|
|
|
|
|
|
|
int clang_Cursor_isNull(CXCursor cursor) {
|
|
|
|
return clang_equalCursors(cursor, clang_getNullCursor());
|
|
|
|
}
|
|
|
|
|
2011-09-27 08:30:30 +08:00
|
|
|
CXTranslationUnit clang_Cursor_getTranslationUnit(CXCursor cursor) {
|
|
|
|
return getCursorTU(cursor);
|
|
|
|
}
|
|
|
|
|
2012-04-12 03:32:19 +08:00
|
|
|
int clang_Cursor_getNumArguments(CXCursor C) {
|
|
|
|
if (clang_isDeclaration(C.kind)) {
|
|
|
|
Decl *D = cxcursor::getCursorDecl(C);
|
|
|
|
if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
|
|
|
|
return MD->param_size();
|
|
|
|
if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
|
|
|
|
return FD->param_size();
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
CXCursor clang_Cursor_getArgument(CXCursor C, unsigned i) {
|
|
|
|
if (clang_isDeclaration(C.kind)) {
|
|
|
|
Decl *D = cxcursor::getCursorDecl(C);
|
|
|
|
if (ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D)) {
|
|
|
|
if (i < MD->param_size())
|
|
|
|
return cxcursor::MakeCXCursor(MD->param_begin()[i],
|
|
|
|
cxcursor::getCursorTU(C));
|
|
|
|
} else if (FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) {
|
|
|
|
if (i < FD->param_size())
|
|
|
|
return cxcursor::MakeCXCursor(FD->param_begin()[i],
|
|
|
|
cxcursor::getCursorTU(C));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return clang_getNullCursor();
|
|
|
|
}
|
|
|
|
|
2011-09-27 12:14:36 +08:00
|
|
|
} // end: extern "C"
|
|
|
|
|
2010-12-09 07:43:14 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// CXCursorSet.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
typedef llvm::DenseMap<CXCursor, unsigned> CXCursorSet_Impl;
|
|
|
|
|
|
|
|
static inline CXCursorSet packCXCursorSet(CXCursorSet_Impl *setImpl) {
|
|
|
|
return (CXCursorSet) setImpl;
|
|
|
|
}
|
|
|
|
static inline CXCursorSet_Impl *unpackCXCursorSet(CXCursorSet set) {
|
|
|
|
return (CXCursorSet_Impl*) set;
|
|
|
|
}
|
|
|
|
namespace llvm {
|
2010-12-09 08:33:41 +08:00
|
|
|
template<> struct DenseMapInfo<CXCursor> {
|
2010-12-09 07:43:14 +08:00
|
|
|
public:
|
|
|
|
static inline CXCursor getEmptyKey() {
|
|
|
|
return MakeCXCursorInvalid(CXCursor_InvalidFile);
|
|
|
|
}
|
|
|
|
static inline CXCursor getTombstoneKey() {
|
|
|
|
return MakeCXCursorInvalid(CXCursor_NoDeclFound);
|
|
|
|
}
|
|
|
|
static inline unsigned getHashValue(const CXCursor &cursor) {
|
|
|
|
return llvm::DenseMapInfo<std::pair<void*,void*> >
|
|
|
|
::getHashValue(std::make_pair(cursor.data[0], cursor.data[1]));
|
|
|
|
}
|
|
|
|
static inline bool isEqual(const CXCursor &x, const CXCursor &y) {
|
|
|
|
return x.kind == y.kind &&
|
|
|
|
x.data[0] == y.data[0] &&
|
|
|
|
x.data[1] == y.data[1];
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
CXCursorSet clang_createCXCursorSet() {
|
|
|
|
return packCXCursorSet(new CXCursorSet_Impl());
|
|
|
|
}
|
|
|
|
|
|
|
|
void clang_disposeCXCursorSet(CXCursorSet set) {
|
|
|
|
delete unpackCXCursorSet(set);
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned clang_CXCursorSet_contains(CXCursorSet set, CXCursor cursor) {
|
|
|
|
CXCursorSet_Impl *setImpl = unpackCXCursorSet(set);
|
|
|
|
if (!setImpl)
|
|
|
|
return 0;
|
|
|
|
return setImpl->find(cursor) == setImpl->end();
|
|
|
|
}
|
|
|
|
|
2010-12-09 09:00:12 +08:00
|
|
|
unsigned clang_CXCursorSet_insert(CXCursorSet set, CXCursor cursor) {
|
2010-12-09 07:43:14 +08:00
|
|
|
// Do not insert invalid cursors into the set.
|
|
|
|
if (cursor.kind >= CXCursor_FirstInvalid &&
|
|
|
|
cursor.kind <= CXCursor_LastInvalid)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
CXCursorSet_Impl *setImpl = unpackCXCursorSet(set);
|
|
|
|
if (!setImpl)
|
|
|
|
return 1;
|
|
|
|
unsigned &entry = (*setImpl)[cursor];
|
|
|
|
unsigned flag = entry == 0 ? 1 : 0;
|
|
|
|
entry = 1;
|
|
|
|
return flag;
|
|
|
|
}
|
2011-08-05 04:04:59 +08:00
|
|
|
|
|
|
|
CXCompletionString clang_getCursorCompletionString(CXCursor cursor) {
|
|
|
|
enum CXCursorKind kind = clang_getCursorKind(cursor);
|
|
|
|
if (clang_isDeclaration(kind)) {
|
|
|
|
Decl *decl = getCursorDecl(cursor);
|
2011-12-10 10:36:25 +08:00
|
|
|
if (NamedDecl *namedDecl = dyn_cast_or_null<NamedDecl>(decl)) {
|
2011-08-05 04:04:59 +08:00
|
|
|
ASTUnit *unit = getCursorASTUnit(cursor);
|
2012-01-17 10:15:54 +08:00
|
|
|
CodeCompletionResult Result(namedDecl);
|
|
|
|
CodeCompletionString *String
|
|
|
|
= Result.CreateCodeCompletionString(unit->getASTContext(),
|
|
|
|
unit->getPreprocessor(),
|
2012-04-11 01:23:48 +08:00
|
|
|
unit->getCodeCompletionTUInfo().getAllocator(),
|
|
|
|
unit->getCodeCompletionTUInfo());
|
2012-01-17 10:15:54 +08:00
|
|
|
return String;
|
2011-08-05 04:04:59 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (kind == CXCursor_MacroDefinition) {
|
|
|
|
MacroDefinition *definition = getCursorMacroDefinition(cursor);
|
|
|
|
const IdentifierInfo *MacroInfo = definition->getName();
|
|
|
|
ASTUnit *unit = getCursorASTUnit(cursor);
|
2012-01-17 10:15:54 +08:00
|
|
|
CodeCompletionResult Result(const_cast<IdentifierInfo *>(MacroInfo));
|
|
|
|
CodeCompletionString *String
|
|
|
|
= Result.CreateCodeCompletionString(unit->getASTContext(),
|
|
|
|
unit->getPreprocessor(),
|
2012-04-11 01:23:48 +08:00
|
|
|
unit->getCodeCompletionTUInfo().getAllocator(),
|
|
|
|
unit->getCodeCompletionTUInfo());
|
2012-01-17 10:15:54 +08:00
|
|
|
return String;
|
2011-08-05 04:04:59 +08:00
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
2012-05-01 03:33:45 +08:00
|
|
|
} // end: extern C.
|
2012-05-01 03:06:49 +08:00
|
|
|
|
|
|
|
namespace {
|
|
|
|
struct OverridenCursorsPool {
|
|
|
|
typedef llvm::SmallVector<CXCursor, 2> CursorVec;
|
|
|
|
std::vector<CursorVec*> AllCursors;
|
|
|
|
std::vector<CursorVec*> AvailableCursors;
|
|
|
|
|
|
|
|
~OverridenCursorsPool() {
|
|
|
|
for (std::vector<CursorVec*>::iterator I = AllCursors.begin(),
|
|
|
|
E = AllCursors.end(); I != E; ++I) {
|
|
|
|
delete *I;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
void *cxcursor::createOverridenCXCursorsPool() {
|
|
|
|
return new OverridenCursorsPool();
|
|
|
|
}
|
|
|
|
|
|
|
|
void cxcursor::disposeOverridenCXCursorsPool(void *pool) {
|
|
|
|
delete static_cast<OverridenCursorsPool*>(pool);
|
|
|
|
}
|
2012-05-01 03:33:45 +08:00
|
|
|
|
|
|
|
extern "C" {
|
2012-05-01 03:06:49 +08:00
|
|
|
void clang_getOverriddenCursors(CXCursor cursor,
|
|
|
|
CXCursor **overridden,
|
|
|
|
unsigned *num_overridden) {
|
|
|
|
if (overridden)
|
|
|
|
*overridden = 0;
|
|
|
|
if (num_overridden)
|
|
|
|
*num_overridden = 0;
|
|
|
|
|
|
|
|
CXTranslationUnit TU = cxcursor::getCursorTU(cursor);
|
|
|
|
|
|
|
|
if (!overridden || !num_overridden || !TU)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!clang_isDeclaration(cursor.kind))
|
|
|
|
return;
|
|
|
|
|
|
|
|
OverridenCursorsPool &pool =
|
|
|
|
*static_cast<OverridenCursorsPool*>(TU->OverridenCursorsPool);
|
|
|
|
|
|
|
|
OverridenCursorsPool::CursorVec *Vec = 0;
|
|
|
|
|
|
|
|
if (!pool.AvailableCursors.empty()) {
|
|
|
|
Vec = pool.AvailableCursors.back();
|
|
|
|
pool.AvailableCursors.pop_back();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
Vec = new OverridenCursorsPool::CursorVec();
|
|
|
|
pool.AllCursors.push_back(Vec);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Clear out the vector, but don't free the memory contents. This
|
|
|
|
// reduces malloc() traffic.
|
|
|
|
Vec->clear();
|
|
|
|
|
|
|
|
// Use the first entry to contain a back reference to the vector.
|
|
|
|
// This is a complete hack.
|
|
|
|
CXCursor backRefCursor = MakeCXCursorInvalid(CXCursor_InvalidFile, TU);
|
|
|
|
backRefCursor.data[0] = Vec;
|
|
|
|
assert(cxcursor::getCursorTU(backRefCursor) == TU);
|
|
|
|
Vec->push_back(backRefCursor);
|
|
|
|
|
|
|
|
// Get the overriden cursors.
|
|
|
|
cxcursor::getOverriddenCursors(cursor, *Vec);
|
|
|
|
|
|
|
|
// Did we get any overriden cursors? If not, return Vec to the pool
|
|
|
|
// of available cursor vectors.
|
|
|
|
if (Vec->size() == 1) {
|
|
|
|
pool.AvailableCursors.push_back(Vec);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now tell the caller about the overriden cursors.
|
|
|
|
assert(Vec->size() > 1);
|
|
|
|
*overridden = &((*Vec)[1]);
|
|
|
|
*num_overridden = Vec->size() - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void clang_disposeOverriddenCursors(CXCursor *overridden) {
|
|
|
|
if (!overridden)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Use pointer arithmetic to get back the first faux entry
|
|
|
|
// which has a back-reference to the TU and the vector.
|
|
|
|
--overridden;
|
|
|
|
OverridenCursorsPool::CursorVec *Vec =
|
|
|
|
static_cast<OverridenCursorsPool::CursorVec*>(overridden->data[0]);
|
|
|
|
CXTranslationUnit TU = getCursorTU(*overridden);
|
|
|
|
|
|
|
|
assert(Vec && TU);
|
|
|
|
|
|
|
|
OverridenCursorsPool &pool =
|
|
|
|
*static_cast<OverridenCursorsPool*>(TU->OverridenCursorsPool);
|
|
|
|
|
|
|
|
pool.AvailableCursors.push_back(Vec);
|
|
|
|
}
|
2011-08-05 04:04:59 +08:00
|
|
|
|
2010-12-09 07:43:14 +08:00
|
|
|
} // end: extern "C"
|