diff options
Diffstat (limited to 'clang/tools')
| -rw-r--r-- | clang/tools/libclang/CIndex.cpp | 80 | ||||
| -rw-r--r-- | clang/tools/libclang/CXCursor.cpp | 17 | ||||
| -rw-r--r-- | clang/tools/libclang/CXCursor.h | 9 |
3 files changed, 102 insertions, 4 deletions
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 5a3084c49ba..cb2f7b53dc4 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -30,6 +30,7 @@ #include "clang/Lex/Lexer.h" #include "clang/Lex/PreprocessingRecord.h" #include "clang/Lex/Preprocessor.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/Support/CrashRecoveryContext.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Timer.h" @@ -697,6 +698,21 @@ bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) { return false; } +/// \brief Compare two base or member initializers based on their source order. +static int CompareCXXBaseOrMemberInitializers(const void* Xp, const void *Yp) { + CXXBaseOrMemberInitializer const * const *X + = static_cast<CXXBaseOrMemberInitializer const * const *>(Xp); + CXXBaseOrMemberInitializer const * const *Y + = static_cast<CXXBaseOrMemberInitializer const * const *>(Yp); + + if ((*X)->getSourceOrder() < (*Y)->getSourceOrder()) + return -1; + else if ((*X)->getSourceOrder() > (*Y)->getSourceOrder()) + return 1; + else + return 0; +} + bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) { if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) { // Visit the function declaration's syntactic components in the order @@ -729,9 +745,45 @@ bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) { // FIXME: Attributes? } - if (ND->isThisDeclarationADefinition() && - Visit(MakeCXCursor(ND->getBody(), StmtParent, TU))) - return true; + if (ND->isThisDeclarationADefinition()) { + if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) { + // Find the initializers that were written in the source. + llvm::SmallVector<CXXBaseOrMemberInitializer *, 4> WrittenInits; + for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(), + IEnd = Constructor->init_end(); + I != IEnd; ++I) { + if (!(*I)->isWritten()) + continue; + + WrittenInits.push_back(*I); + } + + // Sort the initializers in source order + llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(), + &CompareCXXBaseOrMemberInitializers); + + // Visit the initializers in source order + for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) { + CXXBaseOrMemberInitializer *Init = WrittenInits[I]; + if (Init->isMemberInitializer()) { + if (Visit(MakeCursorMemberRef(Init->getMember(), + Init->getMemberLocation(), TU))) + return true; + } else if (TypeSourceInfo *BaseInfo = Init->getBaseClassInfo()) { + if (Visit(BaseInfo->getTypeLoc())) + return true; + } + + // Visit the initializer value. + if (Expr *Initializer = Init->getInit()) + if (Visit(MakeCXCursor(Initializer, ND, TU))) + return true; + } + } + + if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU))) + return true; + } return false; } @@ -2485,6 +2537,13 @@ CXString clang_getCursorSpelling(CXCursor C) { return createCXString(NS->getNameAsString()); } + case CXCursor_MemberRef: { + FieldDecl *Field = getCursorMemberRef(C).first; + assert(Field && "Missing member decl"); + + return createCXString(Field->getNameAsString()); + } + default: return createCXString("<not implemented>"); } @@ -2567,6 +2626,8 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) { return createCXString("TemplateRef"); case CXCursor_NamespaceRef: return createCXString("NamespaceRef"); + case CXCursor_MemberRef: + return createCXString("MemberRef"); case CXCursor_UnexposedExpr: return createCXString("UnexposedExpr"); case CXCursor_BlockExpr: @@ -2769,6 +2830,11 @@ CXSourceLocation clang_getCursorLocation(CXCursor C) { return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); } + case CXCursor_MemberRef: { + std::pair<FieldDecl *, SourceLocation> P = getCursorMemberRef(C); + return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); + } + case CXCursor_CXXBaseSpecifier: { // FIXME: Figure out what location to return for a CXXBaseSpecifier. return clang_getNullLocation(); @@ -2832,7 +2898,10 @@ static SourceRange getRawCursorExtent(CXCursor C) { case CXCursor_NamespaceRef: return getCursorNamespaceRef(C).second; - + + case CXCursor_MemberRef: + return getCursorMemberRef(C).second; + case CXCursor_CXXBaseSpecifier: // FIXME: Figure out what source range to use for a CXBaseSpecifier. return SourceRange(); @@ -2916,6 +2985,9 @@ CXCursor clang_getCursorReferenced(CXCursor C) { case CXCursor_NamespaceRef: return MakeCXCursor(getCursorNamespaceRef(C).first, CXXUnit); + case CXCursor_MemberRef: + return MakeCXCursor(getCursorMemberRef(C).first, CXXUnit); + case CXCursor_CXXBaseSpecifier: { CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C); return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(), diff --git a/clang/tools/libclang/CXCursor.cpp b/clang/tools/libclang/CXCursor.cpp index 9b3ecbf0d93..53145a67194 100644 --- a/clang/tools/libclang/CXCursor.cpp +++ b/clang/tools/libclang/CXCursor.cpp @@ -291,6 +291,23 @@ cxcursor::getCursorNamespaceRef(CXCursor C) { reinterpret_cast<uintptr_t>(C.data[1]))); } +CXCursor cxcursor::MakeCursorMemberRef(FieldDecl *Field, SourceLocation Loc, + ASTUnit *TU) { + + 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]))); +} + CXCursor cxcursor::MakeCursorCXXBaseSpecifier(CXXBaseSpecifier *B, ASTUnit *TU){ CXCursor C = { CXCursor_CXXBaseSpecifier, { B, 0, TU } }; return C; diff --git a/clang/tools/libclang/CXCursor.h b/clang/tools/libclang/CXCursor.h index a5f111edc1d..eff71f398a3 100644 --- a/clang/tools/libclang/CXCursor.h +++ b/clang/tools/libclang/CXCursor.h @@ -26,6 +26,7 @@ class Attr; class CXXBaseSpecifier; class Decl; class Expr; +class FieldDecl; class MacroDefinition; class MacroInstantiation; class NamedDecl; @@ -93,6 +94,14 @@ CXCursor MakeCursorNamespaceRef(NamedDecl *NS, SourceLocation Loc, ASTUnit *TU); /// it references and the location where the reference occurred. std::pair<NamedDecl *, SourceLocation> getCursorNamespaceRef(CXCursor C); +/// \brief Create a reference to a field at the given location. +CXCursor MakeCursorMemberRef(FieldDecl *Field, SourceLocation Loc, + ASTUnit *TU); + +/// \brief Unpack a MemberRef cursor into the field it references and the +/// location where the reference occurred. +std::pair<FieldDecl *, SourceLocation> getCursorMemberRef(CXCursor C); + /// \brief Create a CXX base specifier cursor. CXCursor MakeCursorCXXBaseSpecifier(CXXBaseSpecifier *B, ASTUnit *TU); |

