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"
|
|
|
|
#include "clang/AST/Expr.h"
|
2010-09-14 06:52:57 +08:00
|
|
|
#include "clang/AST/ExprCXX.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
|
|
|
|
2010-01-21 07:34:41 +08:00
|
|
|
CXCursor cxcursor::MakeCXCursorInvalid(CXCursorKind K) {
|
|
|
|
assert(K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid);
|
|
|
|
CXCursor C = { K, { 0, 0, 0 } };
|
|
|
|
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;
|
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!");
|
|
|
|
CXCursor C = { GetCursorKind(A), { Parent, (void*)A, TU } };
|
|
|
|
return C;
|
|
|
|
}
|
|
|
|
|
2010-11-16 16:15:36 +08:00
|
|
|
CXCursor cxcursor::MakeCXCursor(Decl *D, CXTranslationUnit TU,
|
2010-11-02 07:26:51 +08:00
|
|
|
bool FirstInDeclGroup) {
|
2010-01-25 08:40:30 +08:00
|
|
|
assert(D && TU && "Invalid arguments!");
|
2010-11-02 07:26:51 +08:00
|
|
|
CXCursor C = { getCursorKindForDecl(D),
|
|
|
|
{ D, (void*) (FirstInDeclGroup ? 1 : 0), TU }
|
|
|
|
};
|
2010-01-21 07:34:41 +08:00
|
|
|
return C;
|
2010-01-16 08:36:30 +08:00
|
|
|
}
|
|
|
|
|
2010-11-16 16:15:36 +08:00
|
|
|
CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent,
|
|
|
|
CXTranslationUnit TU) {
|
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;
|
|
|
|
|
|
|
|
case Stmt::NullStmtClass:
|
|
|
|
case Stmt::CompoundStmtClass:
|
|
|
|
case Stmt::CaseStmtClass:
|
|
|
|
case Stmt::DefaultStmtClass:
|
|
|
|
case Stmt::IfStmtClass:
|
|
|
|
case Stmt::SwitchStmtClass:
|
|
|
|
case Stmt::WhileStmtClass:
|
|
|
|
case Stmt::DoStmtClass:
|
|
|
|
case Stmt::ForStmtClass:
|
|
|
|
case Stmt::GotoStmtClass:
|
|
|
|
case Stmt::IndirectGotoStmtClass:
|
|
|
|
case Stmt::ContinueStmtClass:
|
|
|
|
case Stmt::BreakStmtClass:
|
|
|
|
case Stmt::ReturnStmtClass:
|
|
|
|
case Stmt::DeclStmtClass:
|
|
|
|
case Stmt::SwitchCaseClass:
|
|
|
|
case Stmt::AsmStmtClass:
|
|
|
|
case Stmt::ObjCAtTryStmtClass:
|
|
|
|
case Stmt::ObjCAtCatchStmtClass:
|
|
|
|
case Stmt::ObjCAtFinallyStmtClass:
|
|
|
|
case Stmt::ObjCAtThrowStmtClass:
|
|
|
|
case Stmt::ObjCAtSynchronizedStmtClass:
|
|
|
|
case Stmt::ObjCForCollectionStmtClass:
|
|
|
|
case Stmt::CXXCatchStmtClass:
|
|
|
|
case Stmt::CXXTryStmtClass:
|
|
|
|
K = CXCursor_UnexposedStmt;
|
|
|
|
break;
|
|
|
|
|
2010-09-10 08:22:18 +08:00
|
|
|
case Stmt::LabelStmtClass:
|
|
|
|
K = CXCursor_LabelStmt;
|
|
|
|
break;
|
|
|
|
|
2010-01-20 07:20:36 +08:00
|
|
|
case Stmt::PredefinedExprClass:
|
|
|
|
case Stmt::IntegerLiteralClass:
|
|
|
|
case Stmt::FloatingLiteralClass:
|
|
|
|
case Stmt::ImaginaryLiteralClass:
|
|
|
|
case Stmt::StringLiteralClass:
|
|
|
|
case Stmt::CharacterLiteralClass:
|
|
|
|
case Stmt::ParenExprClass:
|
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:
|
|
|
|
case Stmt::OffsetOfExprClass:
|
2010-01-20 07:20:36 +08:00
|
|
|
case Stmt::SizeOfAlignOfExprClass:
|
|
|
|
case Stmt::ArraySubscriptExprClass:
|
|
|
|
case Stmt::BinaryOperatorClass:
|
|
|
|
case Stmt::CompoundAssignOperatorClass:
|
|
|
|
case Stmt::ConditionalOperatorClass:
|
|
|
|
case Stmt::ImplicitCastExprClass:
|
|
|
|
case Stmt::CStyleCastExprClass:
|
|
|
|
case Stmt::CompoundLiteralExprClass:
|
|
|
|
case Stmt::ExtVectorElementExprClass:
|
|
|
|
case Stmt::InitListExprClass:
|
|
|
|
case Stmt::DesignatedInitExprClass:
|
|
|
|
case Stmt::ImplicitValueInitExprClass:
|
|
|
|
case Stmt::ParenListExprClass:
|
|
|
|
case Stmt::VAArgExprClass:
|
|
|
|
case Stmt::AddrLabelExprClass:
|
|
|
|
case Stmt::StmtExprClass:
|
|
|
|
case Stmt::ChooseExprClass:
|
|
|
|
case Stmt::GNUNullExprClass:
|
|
|
|
case Stmt::CXXStaticCastExprClass:
|
|
|
|
case Stmt::CXXDynamicCastExprClass:
|
|
|
|
case Stmt::CXXReinterpretCastExprClass:
|
|
|
|
case Stmt::CXXConstCastExprClass:
|
|
|
|
case Stmt::CXXFunctionalCastExprClass:
|
|
|
|
case Stmt::CXXTypeidExprClass:
|
2010-09-09 07:47:05 +08:00
|
|
|
case Stmt::CXXUuidofExprClass:
|
2010-01-20 07:20:36 +08:00
|
|
|
case Stmt::CXXBoolLiteralExprClass:
|
|
|
|
case Stmt::CXXNullPtrLiteralExprClass:
|
|
|
|
case Stmt::CXXThisExprClass:
|
|
|
|
case Stmt::CXXThrowExprClass:
|
|
|
|
case Stmt::CXXDefaultArgExprClass:
|
2010-07-08 14:14:04 +08:00
|
|
|
case Stmt::CXXScalarValueInitExprClass:
|
2010-01-20 07:20:36 +08:00
|
|
|
case Stmt::CXXNewExprClass:
|
|
|
|
case Stmt::CXXDeleteExprClass:
|
|
|
|
case Stmt::CXXPseudoDestructorExprClass:
|
|
|
|
case Stmt::UnresolvedLookupExprClass:
|
|
|
|
case Stmt::UnaryTypeTraitExprClass:
|
2010-12-07 08:08:36 +08:00
|
|
|
case Stmt::BinaryTypeTraitExprClass:
|
2010-01-20 07:20:36 +08:00
|
|
|
case Stmt::DependentScopeDeclRefExprClass:
|
|
|
|
case Stmt::CXXBindTemporaryExprClass:
|
2010-12-06 16:20:24 +08:00
|
|
|
case Stmt::ExprWithCleanupsClass:
|
2010-01-20 07:20:36 +08:00
|
|
|
case Stmt::CXXUnresolvedConstructExprClass:
|
|
|
|
case Stmt::CXXDependentScopeMemberExprClass:
|
|
|
|
case Stmt::UnresolvedMemberExprClass:
|
2010-09-11 04:55:43 +08:00
|
|
|
case Stmt::CXXNoexceptExprClass:
|
2010-01-20 07:20:36 +08:00
|
|
|
case Stmt::ObjCStringLiteralClass:
|
|
|
|
case Stmt::ObjCEncodeExprClass:
|
|
|
|
case Stmt::ObjCSelectorExprClass:
|
|
|
|
case Stmt::ObjCProtocolExprClass:
|
|
|
|
case Stmt::ObjCIsaExprClass:
|
|
|
|
case Stmt::ShuffleVectorExprClass:
|
|
|
|
case Stmt::BlockExprClass:
|
2010-11-16 07:31:06 +08:00
|
|
|
case Stmt::OpaqueValueExprClass:
|
2010-01-20 07:20:36 +08:00
|
|
|
K = CXCursor_UnexposedExpr;
|
|
|
|
break;
|
2010-09-10 08:22:18 +08:00
|
|
|
|
2010-01-20 07:20:36 +08:00
|
|
|
case Stmt::DeclRefExprClass:
|
|
|
|
case Stmt::BlockDeclRefExprClass:
|
|
|
|
// FIXME: UnresolvedLookupExpr?
|
|
|
|
// FIXME: DependentScopeDeclRefExpr?
|
|
|
|
K = CXCursor_DeclRefExpr;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::MemberExprClass:
|
|
|
|
case Stmt::ObjCIvarRefExprClass:
|
|
|
|
case Stmt::ObjCPropertyRefExprClass:
|
|
|
|
// FIXME: UnresolvedMemberExpr?
|
|
|
|
// FIXME: CXXDependentScopeMemberExpr?
|
|
|
|
K = CXCursor_MemberRefExpr;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::CallExprClass:
|
|
|
|
case Stmt::CXXOperatorCallExprClass:
|
|
|
|
case Stmt::CXXMemberCallExprClass:
|
|
|
|
case Stmt::CXXConstructExprClass:
|
|
|
|
case Stmt::CXXTemporaryObjectExprClass:
|
|
|
|
// FIXME: CXXUnresolvedConstructExpr
|
|
|
|
K = CXCursor_CallExpr;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Stmt::ObjCMessageExprClass:
|
|
|
|
K = CXCursor_ObjCMessageExpr;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2010-01-21 07:57:43 +08:00
|
|
|
CXCursor C = { K, { 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());
|
2010-01-21 07:57:43 +08:00
|
|
|
CXCursor C = { CXCursor_ObjCSuperClassRef, { 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])));
|
|
|
|
}
|
|
|
|
|
2010-01-16 23:44:18 +08:00
|
|
|
CXCursor cxcursor::MakeCursorObjCProtocolRef(ObjCProtocolDecl *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 23:44:18 +08:00
|
|
|
void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
|
2010-01-21 07:57:43 +08:00
|
|
|
CXCursor C = { CXCursor_ObjCProtocolRef, { Super, 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])));
|
|
|
|
}
|
|
|
|
|
2010-01-17 01:14:40 +08:00
|
|
|
CXCursor cxcursor::MakeCursorObjCClassRef(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());
|
2010-01-21 07:57:43 +08:00
|
|
|
CXCursor C = { CXCursor_ObjCClassRef, { 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])));
|
|
|
|
}
|
|
|
|
|
2010-01-22 00:28:34 +08:00
|
|
|
CXCursor cxcursor::MakeCursorTypeRef(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());
|
|
|
|
CXCursor C = { CXCursor_TypeRef, { Type, RawLoc, TU } };
|
|
|
|
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])));
|
|
|
|
}
|
|
|
|
|
2010-09-01 04:37:03 +08:00
|
|
|
CXCursor cxcursor::MakeCursorTemplateRef(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());
|
|
|
|
CXCursor C = { CXCursor_TemplateRef, { Template, RawLoc, TU } };
|
|
|
|
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])));
|
|
|
|
}
|
|
|
|
|
2010-09-01 07:48:11 +08:00
|
|
|
CXCursor cxcursor::MakeCursorNamespaceRef(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());
|
|
|
|
CXCursor C = { CXCursor_NamespaceRef, { NS, RawLoc, TU } };
|
|
|
|
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])));
|
|
|
|
}
|
|
|
|
|
2010-09-10 05:42:20 +08:00
|
|
|
CXCursor cxcursor::MakeCursorMemberRef(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());
|
|
|
|
CXCursor C = { CXCursor_MemberRef, { Field, RawLoc, TU } };
|
|
|
|
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])));
|
|
|
|
}
|
|
|
|
|
2010-11-16 16:15:36 +08:00
|
|
|
CXCursor cxcursor::MakeCursorCXXBaseSpecifier(CXXBaseSpecifier *B,
|
|
|
|
CXTranslationUnit TU){
|
2010-08-28 05:34:58 +08:00
|
|
|
CXCursor C = { CXCursor_CXXBaseSpecifier, { B, 0, TU } };
|
|
|
|
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) {
|
2010-03-18 08:42:48 +08:00
|
|
|
CXCursor C = { CXCursor_PreprocessingDirective,
|
|
|
|
{ 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);
|
2010-03-18 23:23:44 +08:00
|
|
|
return SourceRange(SourceLocation::getFromRawEncoding(
|
|
|
|
reinterpret_cast<uintptr_t> (C.data[0])),
|
|
|
|
SourceLocation::getFromRawEncoding(
|
|
|
|
reinterpret_cast<uintptr_t> (C.data[1])));
|
|
|
|
}
|
|
|
|
|
2010-11-16 16:15:36 +08:00
|
|
|
CXCursor cxcursor::MakeMacroDefinitionCursor(MacroDefinition *MI,
|
|
|
|
CXTranslationUnit TU) {
|
2010-03-19 02:04:21 +08:00
|
|
|
CXCursor C = { CXCursor_MacroDefinition, { MI, 0, TU } };
|
|
|
|
return C;
|
|
|
|
}
|
|
|
|
|
|
|
|
MacroDefinition *cxcursor::getCursorMacroDefinition(CXCursor C) {
|
|
|
|
assert(C.kind == CXCursor_MacroDefinition);
|
|
|
|
return static_cast<MacroDefinition *>(C.data[0]);
|
|
|
|
}
|
|
|
|
|
Introduce the notion of a "preprocessing record", which keeps track of
the macro definitions and macro instantiations that are found
during preprocessing. Preprocessing records are *not* generated by
default; rather, we provide a PPCallbacks subclass that hooks into the
existing callback mechanism to record this activity.
The only client of preprocessing records is CIndex, which keeps track
of macro definitions and instantations so that they can be exposed via
cursors. At present, only token annotation uses these facilities, and
only for macro instantiations; both will change in the near
future. However, with this change, token annotation properly annotates
macro instantiations that do not produce any tokens and instantiations
of macros that are later undef'd, improving our consistency.
Preprocessing directives that are not macro definitions are still
handled by clang_annotateTokens() via re-lexing, so that we don't have
to track every preprocessing directive in the preprocessing record.
Performance impact of preprocessing records is still TBD, although it
is limited to CIndex and therefore out of the path of the main compiler.
llvm-svn: 98836
2010-03-19 01:52:52 +08:00
|
|
|
CXCursor cxcursor::MakeMacroInstantiationCursor(MacroInstantiation *MI,
|
2010-11-16 16:15:36 +08:00
|
|
|
CXTranslationUnit TU) {
|
Introduce the notion of a "preprocessing record", which keeps track of
the macro definitions and macro instantiations that are found
during preprocessing. Preprocessing records are *not* generated by
default; rather, we provide a PPCallbacks subclass that hooks into the
existing callback mechanism to record this activity.
The only client of preprocessing records is CIndex, which keeps track
of macro definitions and instantations so that they can be exposed via
cursors. At present, only token annotation uses these facilities, and
only for macro instantiations; both will change in the near
future. However, with this change, token annotation properly annotates
macro instantiations that do not produce any tokens and instantiations
of macros that are later undef'd, improving our consistency.
Preprocessing directives that are not macro definitions are still
handled by clang_annotateTokens() via re-lexing, so that we don't have
to track every preprocessing directive in the preprocessing record.
Performance impact of preprocessing records is still TBD, although it
is limited to CIndex and therefore out of the path of the main compiler.
llvm-svn: 98836
2010-03-19 01:52:52 +08:00
|
|
|
CXCursor C = { CXCursor_MacroInstantiation, { MI, 0, TU } };
|
2010-03-18 23:23:44 +08:00
|
|
|
return C;
|
|
|
|
}
|
|
|
|
|
Introduce the notion of a "preprocessing record", which keeps track of
the macro definitions and macro instantiations that are found
during preprocessing. Preprocessing records are *not* generated by
default; rather, we provide a PPCallbacks subclass that hooks into the
existing callback mechanism to record this activity.
The only client of preprocessing records is CIndex, which keeps track
of macro definitions and instantations so that they can be exposed via
cursors. At present, only token annotation uses these facilities, and
only for macro instantiations; both will change in the near
future. However, with this change, token annotation properly annotates
macro instantiations that do not produce any tokens and instantiations
of macros that are later undef'd, improving our consistency.
Preprocessing directives that are not macro definitions are still
handled by clang_annotateTokens() via re-lexing, so that we don't have
to track every preprocessing directive in the preprocessing record.
Performance impact of preprocessing records is still TBD, although it
is limited to CIndex and therefore out of the path of the main compiler.
llvm-svn: 98836
2010-03-19 01:52:52 +08:00
|
|
|
MacroInstantiation *cxcursor::getCursorMacroInstantiation(CXCursor C) {
|
2010-03-18 23:23:44 +08:00
|
|
|
assert(C.kind == CXCursor_MacroInstantiation);
|
Introduce the notion of a "preprocessing record", which keeps track of
the macro definitions and macro instantiations that are found
during preprocessing. Preprocessing records are *not* generated by
default; rather, we provide a PPCallbacks subclass that hooks into the
existing callback mechanism to record this activity.
The only client of preprocessing records is CIndex, which keeps track
of macro definitions and instantations so that they can be exposed via
cursors. At present, only token annotation uses these facilities, and
only for macro instantiations; both will change in the near
future. However, with this change, token annotation properly annotates
macro instantiations that do not produce any tokens and instantiations
of macros that are later undef'd, improving our consistency.
Preprocessing directives that are not macro definitions are still
handled by clang_annotateTokens() via re-lexing, so that we don't have
to track every preprocessing directive in the preprocessing record.
Performance impact of preprocessing records is still TBD, although it
is limited to CIndex and therefore out of the path of the main compiler.
llvm-svn: 98836
2010-03-19 01:52:52 +08:00
|
|
|
return static_cast<MacroInstantiation *>(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) {
|
2010-10-21 06:00:55 +08:00
|
|
|
CXCursor C = { CXCursor_InclusionDirective, { ID, 0, TU } };
|
|
|
|
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());
|
|
|
|
CXCursor C = { CXCursor_LabelRef, { Label, RawLoc, TU } };
|
|
|
|
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 = {
|
|
|
|
CXCursor_OverloadedDeclRef,
|
|
|
|
{ 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 = {
|
|
|
|
CXCursor_OverloadedDeclRef,
|
|
|
|
{ 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 = {
|
|
|
|
CXCursor_OverloadedDeclRef,
|
|
|
|
{ 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];
|
|
|
|
}
|
|
|
|
|
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) {
|
2010-11-16 16:15:36 +08:00
|
|
|
return static_cast<ASTUnit *>(static_cast<CXTranslationUnit>(Cursor.data[2])
|
|
|
|
->TUData);
|
|
|
|
}
|
|
|
|
|
|
|
|
CXTranslationUnit cxcursor::getCursorTU(CXCursor Cursor) {
|
|
|
|
return static_cast<CXTranslationUnit>(Cursor.data[2]);
|
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;
|
|
|
|
}
|
|
|
|
|