summaryrefslogtreecommitdiffstats
path: root/tools/libclang
diff options
context:
space:
mode:
Diffstat (limited to 'tools/libclang')
-rw-r--r--tools/libclang/CIndex.cpp91
-rw-r--r--tools/libclang/CIndexCXX.cpp2
-rw-r--r--tools/libclang/CXCursor.cpp24
-rw-r--r--tools/libclang/CXSourceLocation.cpp11
-rw-r--r--tools/libclang/CXTranslationUnit.h2
-rw-r--r--tools/libclang/CXType.cpp132
-rw-r--r--tools/libclang/IndexBody.cpp9
-rw-r--r--tools/libclang/IndexDecl.cpp5
-rw-r--r--tools/libclang/Indexing.cpp9
-rw-r--r--tools/libclang/IndexingContext.cpp6
-rw-r--r--tools/libclang/IndexingContext.h3
-rw-r--r--tools/libclang/RecursiveASTVisitor.h28
-rw-r--r--tools/libclang/libclang.exports9
13 files changed, 311 insertions, 20 deletions
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index a81f1e4..a43c1ab 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -723,6 +723,13 @@ bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
}
bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
+ unsigned NumParamList = DD->getNumTemplateParameterLists();
+ for (unsigned i = 0; i < NumParamList; i++) {
+ TemplateParameterList* Params = DD->getTemplateParameterList(i);
+ if (VisitTemplateParameters(Params))
+ return true;
+ }
+
if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
if (Visit(TSInfo->getTypeLoc()))
return true;
@@ -751,6 +758,13 @@ static int CompareCXXCtorInitializers(const void* Xp, const void *Yp) {
}
bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
+ unsigned NumParamList = ND->getNumTemplateParameterLists();
+ for (unsigned i = 0; i < NumParamList; i++) {
+ TemplateParameterList* Params = ND->getTemplateParameterList(i);
+ if (VisitTemplateParameters(Params))
+ return true;
+ }
+
if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
// Visit the function declaration's syntactic components in the order
// written. This requires a bit of work.
@@ -3574,6 +3588,8 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
return cxstring::createRef("ObjCStringLiteral");
case CXCursor_ObjCBoolLiteralExpr:
return cxstring::createRef("ObjCBoolLiteralExpr");
+ case CXCursor_ObjCSelfExpr:
+ return cxstring::createRef("ObjCSelfExpr");
case CXCursor_ObjCEncodeExpr:
return cxstring::createRef("ObjCEncodeExpr");
case CXCursor_ObjCSelectorExpr:
@@ -4444,6 +4460,7 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
case Decl::TemplateTypeParm:
case Decl::EnumConstant:
case Decl::Field:
+ case Decl::MSProperty:
case Decl::IndirectField:
case Decl::ObjCIvar:
case Decl::ObjCAtDefsField:
@@ -4459,6 +4476,7 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
case Decl::FileScopeAsm:
case Decl::StaticAssert:
case Decl::Block:
+ case Decl::Captured:
case Decl::Label: // FIXME: Is this right??
case Decl::ClassScopeFunctionSpecialization:
case Decl::Import:
@@ -5903,6 +5921,72 @@ CXFile clang_getIncludedFile(CXCursor cursor) {
return const_cast<FileEntry *>(ID->getFile());
}
+unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
+ if (C.kind != CXCursor_ObjCPropertyDecl)
+ return CXObjCPropertyAttr_noattr;
+
+ unsigned Result = CXObjCPropertyAttr_noattr;
+ const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
+ ObjCPropertyDecl::PropertyAttributeKind Attr =
+ PD->getPropertyAttributesAsWritten();
+
+#define SET_CXOBJCPROP_ATTR(A) \
+ if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
+ Result |= CXObjCPropertyAttr_##A
+ SET_CXOBJCPROP_ATTR(readonly);
+ SET_CXOBJCPROP_ATTR(getter);
+ SET_CXOBJCPROP_ATTR(assign);
+ SET_CXOBJCPROP_ATTR(readwrite);
+ SET_CXOBJCPROP_ATTR(retain);
+ SET_CXOBJCPROP_ATTR(copy);
+ SET_CXOBJCPROP_ATTR(nonatomic);
+ SET_CXOBJCPROP_ATTR(setter);
+ SET_CXOBJCPROP_ATTR(atomic);
+ SET_CXOBJCPROP_ATTR(weak);
+ SET_CXOBJCPROP_ATTR(strong);
+ SET_CXOBJCPROP_ATTR(unsafe_unretained);
+#undef SET_CXOBJCPROP_ATTR
+
+ return Result;
+}
+
+unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
+ if (!clang_isDeclaration(C.kind))
+ return CXObjCDeclQualifier_None;
+
+ Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
+ const Decl *D = getCursorDecl(C);
+ if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
+ QT = MD->getObjCDeclQualifier();
+ else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
+ QT = PD->getObjCDeclQualifier();
+ if (QT == Decl::OBJC_TQ_None)
+ return CXObjCDeclQualifier_None;
+
+ unsigned Result = CXObjCDeclQualifier_None;
+ if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
+ if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
+ if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
+ if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
+ if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
+ if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
+
+ return Result;
+}
+
+unsigned clang_Cursor_isVariadic(CXCursor C) {
+ if (!clang_isDeclaration(C.kind))
+ return 0;
+
+ const Decl *D = getCursorDecl(C);
+ if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+ return FD->isVariadic();
+ if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
+ return MD->isVariadic();
+
+ return 0;
+}
+
CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
if (!clang_isDeclaration(C.kind))
return clang_getNullRange();
@@ -5971,6 +6055,13 @@ CXModule clang_Cursor_getModule(CXCursor C) {
return 0;
}
+CXFile clang_Module_getASTFile(CXModule CXMod) {
+ if (!CXMod)
+ return 0;
+ Module *Mod = static_cast<Module*>(CXMod);
+ return const_cast<FileEntry *>(Mod->getASTFile());
+}
+
CXModule clang_Module_getParent(CXModule CXMod) {
if (!CXMod)
return 0;
diff --git a/tools/libclang/CIndexCXX.cpp b/tools/libclang/CIndexCXX.cpp
index c68dde7..a3d2364 100644
--- a/tools/libclang/CIndexCXX.cpp
+++ b/tools/libclang/CIndexCXX.cpp
@@ -33,7 +33,7 @@ unsigned clang_isVirtualBase(CXCursor C) {
enum CX_CXXAccessSpecifier clang_getCXXAccessSpecifier(CXCursor C) {
AccessSpecifier spec = AS_none;
- if (C.kind == CXCursor_CXXAccessSpecifier)
+ if (C.kind == CXCursor_CXXAccessSpecifier || clang_isDeclaration(C.kind))
spec = getCursorDecl(C)->getAccess();
else if (C.kind == CXCursor_CXXBaseSpecifier)
spec = getCursorCXXBaseSpecifier(C)->getAccessSpecifier();
diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp
index 7b01ec2..2cdb71b 100644
--- a/tools/libclang/CXCursor.cpp
+++ b/tools/libclang/CXCursor.cpp
@@ -215,6 +215,7 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent,
case Stmt::TypeTraitExprClass:
case Stmt::CXXBindTemporaryExprClass:
case Stmt::CXXDefaultArgExprClass:
+ case Stmt::CXXDefaultInitExprClass:
case Stmt::CXXScalarValueInitExprClass:
case Stmt::CXXUuidofExprClass:
case Stmt::ChooseExprClass:
@@ -270,6 +271,10 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent,
K = CXCursor_DeclStmt;
break;
+ case Stmt::CapturedStmtClass:
+ K = CXCursor_UnexposedStmt;
+ break;
+
case Stmt::IntegerLiteralClass:
K = CXCursor_IntegerLiteral;
break;
@@ -430,7 +435,21 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent,
K = CXCursor_SizeOfPackExpr;
break;
- case Stmt::DeclRefExprClass:
+ case Stmt::DeclRefExprClass:
+ if (const ImplicitParamDecl *IPD =
+ dyn_cast_or_null<ImplicitParamDecl>(cast<DeclRefExpr>(S)->getDecl())) {
+ if (const ObjCMethodDecl *MD =
+ dyn_cast<ObjCMethodDecl>(IPD->getDeclContext())) {
+ if (MD->getSelfDecl() == IPD) {
+ K = CXCursor_ObjCSelfExpr;
+ break;
+ }
+ }
+ }
+
+ K = CXCursor_DeclRefExpr;
+ break;
+
case Stmt::DependentScopeDeclRefExprClass:
case Stmt::SubstNonTypeTemplateParmExprClass:
case Stmt::SubstNonTypeTemplateParmPackExprClass:
@@ -442,6 +461,7 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent,
case Stmt::CXXDependentScopeMemberExprClass:
case Stmt::CXXPseudoDestructorExprClass:
case Stmt::MemberExprClass:
+ case Stmt::MSPropertyRefExprClass:
case Stmt::ObjCIsaExprClass:
case Stmt::ObjCIvarRefExprClass:
case Stmt::ObjCPropertyRefExprClass:
@@ -1025,7 +1045,7 @@ unsigned clang_CXCursorSet_contains(CXCursorSet set, CXCursor cursor) {
CXCursorSet_Impl *setImpl = unpackCXCursorSet(set);
if (!setImpl)
return 0;
- return setImpl->find(cursor) == setImpl->end();
+ return setImpl->find(cursor) != setImpl->end();
}
unsigned clang_CXCursorSet_insert(CXCursorSet set, CXCursor cursor) {
diff --git a/tools/libclang/CXSourceLocation.cpp b/tools/libclang/CXSourceLocation.cpp
index bc8d575..b7c7622 100644
--- a/tools/libclang/CXSourceLocation.cpp
+++ b/tools/libclang/CXSourceLocation.cpp
@@ -198,6 +198,17 @@ static void createNullLocation(CXString *filename, unsigned *line,
extern "C" {
+int clang_Location_isInSystemHeader(CXSourceLocation location) {
+ const SourceLocation Loc =
+ SourceLocation::getFromRawEncoding(location.int_data);
+ if (Loc.isInvalid())
+ return 0;
+
+ const SourceManager &SM =
+ *static_cast<const SourceManager*>(location.ptr_data[0]);
+ return SM.isInSystemHeader(Loc);
+}
+
void clang_getExpansionLocation(CXSourceLocation location,
CXFile *file,
unsigned *line,
diff --git a/tools/libclang/CXTranslationUnit.h b/tools/libclang/CXTranslationUnit.h
index 699b74a..bdc171c 100644
--- a/tools/libclang/CXTranslationUnit.h
+++ b/tools/libclang/CXTranslationUnit.h
@@ -39,6 +39,8 @@ namespace cxtu {
CXTranslationUnitImpl *MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU);
static inline ASTUnit *getASTUnit(CXTranslationUnit TU) {
+ if (!TU)
+ return 0;
return TU->TheASTUnit;
}
diff --git a/tools/libclang/CXType.cpp b/tools/libclang/CXType.cpp
index 6f87fc5..1482415 100644
--- a/tools/libclang/CXType.cpp
+++ b/tools/libclang/CXType.cpp
@@ -149,14 +149,20 @@ CXType clang_getCursorType(CXCursor C) {
return MakeCXType(Context.getTypeDeclType(TD), TU);
if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
return MakeCXType(Context.getObjCInterfaceType(ID), TU);
+ if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
+ if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
+ return MakeCXType(TSInfo->getType(), TU);
+ return MakeCXType(DD->getType(), TU);
+ }
if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
return MakeCXType(VD->getType(), TU);
if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
return MakeCXType(PD->getType(), TU);
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
- return MakeCXType(FD->getType(), TU);
- if (const FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(D))
+ if (const FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(D)) {
+ if (TypeSourceInfo *TSInfo = FTD->getTemplatedDecl()->getTypeSourceInfo())
+ return MakeCXType(TSInfo->getType(), TU);
return MakeCXType(FTD->getTemplatedDecl()->getType(), TU);
+ }
return MakeCXType(QualType(), TU);
}
@@ -651,6 +657,126 @@ long long clang_getArraySize(CXType CT) {
return result;
}
+long long clang_Type_getAlignOf(CXType T) {
+ if (T.kind == CXType_Invalid)
+ return CXTypeLayoutError_Invalid;
+ ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext();
+ QualType QT = GetQualType(T);
+ // [expr.alignof] p1: return size_t value for complete object type, reference
+ // or array.
+ // [expr.alignof] p3: if reference type, return size of referenced type
+ if (QT->isReferenceType())
+ QT = QT.getNonReferenceType();
+ if (QT->isIncompleteType())
+ return CXTypeLayoutError_Incomplete;
+ if (QT->isDependentType())
+ return CXTypeLayoutError_Dependent;
+ // Exceptions by GCC extension - see ASTContext.cpp:1313 getTypeInfoImpl
+ // if (QT->isFunctionType()) return 4; // Bug #15511 - should be 1
+ // if (QT->isVoidType()) return 1;
+ return Ctx.getTypeAlignInChars(QT).getQuantity();
+}
+
+long long clang_Type_getSizeOf(CXType T) {
+ if (T.kind == CXType_Invalid)
+ return CXTypeLayoutError_Invalid;
+ ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext();
+ QualType QT = GetQualType(T);
+ // [expr.sizeof] p2: if reference type, return size of referenced type
+ if (QT->isReferenceType())
+ QT = QT.getNonReferenceType();
+ // [expr.sizeof] p1: return -1 on: func, incomplete, bitfield, incomplete
+ // enumeration
+ // Note: We get the cxtype, not the cxcursor, so we can't call
+ // FieldDecl->isBitField()
+ // [expr.sizeof] p3: pointer ok, function not ok.
+ // [gcc extension] lib/AST/ExprConstant.cpp:1372 HandleSizeof : vla == error
+ if (QT->isIncompleteType())
+ return CXTypeLayoutError_Incomplete;
+ if (QT->isDependentType())
+ return CXTypeLayoutError_Dependent;
+ if (!QT->isConstantSizeType())
+ return CXTypeLayoutError_NotConstantSize;
+ // [gcc extension] lib/AST/ExprConstant.cpp:1372
+ // HandleSizeof : {voidtype,functype} == 1
+ // not handled by ASTContext.cpp:1313 getTypeInfoImpl
+ if (QT->isVoidType() || QT->isFunctionType())
+ return 1;
+ return Ctx.getTypeSizeInChars(QT).getQuantity();
+}
+
+static long long visitRecordForValidation(const RecordDecl *RD) {
+ for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
+ I != E; ++I){
+ QualType FQT = (*I)->getType();
+ if (FQT->isIncompleteType())
+ return CXTypeLayoutError_Incomplete;
+ if (FQT->isDependentType())
+ return CXTypeLayoutError_Dependent;
+ // recurse
+ if (const RecordType *ChildType = (*I)->getType()->getAs<RecordType>()) {
+ if (const RecordDecl *Child = ChildType->getDecl()) {
+ long long ret = visitRecordForValidation(Child);
+ if (ret < 0)
+ return ret;
+ }
+ }
+ // else try next field
+ }
+ return 0;
+}
+
+long long clang_Type_getOffsetOf(CXType PT, const char *S) {
+ // check that PT is not incomplete/dependent
+ CXCursor PC = clang_getTypeDeclaration(PT);
+ if (clang_isInvalid(PC.kind))
+ return CXTypeLayoutError_Invalid;
+ const RecordDecl *RD =
+ dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
+ if (!RD)
+ return CXTypeLayoutError_Invalid;
+ RD = RD->getDefinition();
+ if (!RD)
+ return CXTypeLayoutError_Incomplete;
+ QualType RT = GetQualType(PT);
+ if (RT->isIncompleteType())
+ return CXTypeLayoutError_Incomplete;
+ if (RT->isDependentType())
+ return CXTypeLayoutError_Dependent;
+ // We recurse into all record fields to detect incomplete and dependent types.
+ long long Error = visitRecordForValidation(RD);
+ if (Error < 0)
+ return Error;
+ if (!S)
+ return CXTypeLayoutError_InvalidFieldName;
+ // lookup field
+ ASTContext &Ctx = cxtu::getASTUnit(GetTU(PT))->getASTContext();
+ IdentifierInfo *II = &Ctx.Idents.get(S);
+ DeclarationName FieldName(II);
+ RecordDecl::lookup_const_result Res = RD->lookup(FieldName);
+ // If a field of the parent record is incomplete, lookup will fail.
+ // and we would return InvalidFieldName instead of Incomplete.
+ // But this erroneous results does protects again a hidden assertion failure
+ // in the RecordLayoutBuilder
+ if (Res.size() != 1)
+ return CXTypeLayoutError_InvalidFieldName;
+ if (const FieldDecl *FD = dyn_cast<FieldDecl>(Res.front()))
+ return Ctx.getFieldOffset(FD);
+ if (const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(Res.front()))
+ return Ctx.getFieldOffset(IFD);
+ // we don't want any other Decl Type.
+ return CXTypeLayoutError_InvalidFieldName;
+}
+
+unsigned clang_Cursor_isBitField(CXCursor C) {
+ if (!clang_isDeclaration(C.kind))
+ return 0;
+ const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(cxcursor::getCursorDecl(C));
+ if (!FD)
+ return 0;
+ return FD->isBitField();
+}
+
CXString clang_getDeclObjCTypeEncoding(CXCursor C) {
if (!clang_isDeclaration(C.kind))
return cxstring::createEmpty();
diff --git a/tools/libclang/IndexBody.cpp b/tools/libclang/IndexBody.cpp
index 95d74ef..02ab885 100644
--- a/tools/libclang/IndexBody.cpp
+++ b/tools/libclang/IndexBody.cpp
@@ -68,9 +68,6 @@ public:
}
bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
- if (TypeSourceInfo *Cls = E->getClassReceiverTypeInfo())
- IndexCtx.indexTypeSourceInfo(Cls, Parent, ParentDC);
-
if (ObjCMethodDecl *MD = E->getMethodDecl())
IndexCtx.handleReference(MD, E->getSelectorStartLoc(),
Parent, ParentDC, E,
@@ -89,6 +86,12 @@ public:
return true;
}
+ bool VisitMSPropertyRefExpr(MSPropertyRefExpr *E) {
+ IndexCtx.handleReference(E->getPropertyDecl(), E->getMemberLoc(), Parent,
+ ParentDC, E, CXIdxEntityRef_Direct);
+ return true;
+ }
+
bool VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
IndexCtx.handleReference(E->getProtocol(), E->getProtocolIdLoc(),
Parent, ParentDC, E, CXIdxEntityRef_Direct);
diff --git a/tools/libclang/IndexDecl.cpp b/tools/libclang/IndexDecl.cpp
index d7fb959..756001c 100644
--- a/tools/libclang/IndexDecl.cpp
+++ b/tools/libclang/IndexDecl.cpp
@@ -105,6 +105,11 @@ public:
return true;
}
+ bool VisitMSPropertyDecl(const MSPropertyDecl *D) {
+ handleDeclarator(D);
+ return true;
+ }
+
bool VisitEnumConstantDecl(const EnumConstantDecl *D) {
IndexCtx.handleEnumerator(D);
IndexCtx.indexBody(D->getInitExpr(), D);
diff --git a/tools/libclang/Indexing.cpp b/tools/libclang/Indexing.cpp
index 2a504db..15786ac 100644
--- a/tools/libclang/Indexing.cpp
+++ b/tools/libclang/Indexing.cpp
@@ -292,7 +292,7 @@ public:
/// MacroExpands - This is called by when a macro invocation is found.
virtual void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD,
- SourceRange Range) {
+ SourceRange Range, const MacroArgs *Args) {
}
/// SourceRangeSkipped - This hook is called when a source range is skipped.
@@ -398,10 +398,6 @@ public:
if (level >= DiagnosticsEngine::Error)
Errors.push_back(StoredDiagnostic(level, Info));
}
-
- DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const {
- return new IgnoringDiagConsumer();
- }
};
//===----------------------------------------------------------------------===//
@@ -549,8 +545,7 @@ static void clang_indexSourceFile_Impl(void *UserData) {
IntrusiveRefCntPtr<DiagnosticsEngine>
Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions,
CaptureDiag,
- /*ShouldOwnClient=*/true,
- /*ShouldCloneClient=*/false));
+ /*ShouldOwnClient=*/true));
// Recover resources if we crash before exiting this function.
llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
diff --git a/tools/libclang/IndexingContext.cpp b/tools/libclang/IndexingContext.cpp
index 3368922..14b430c 100644
--- a/tools/libclang/IndexingContext.cpp
+++ b/tools/libclang/IndexingContext.cpp
@@ -396,6 +396,12 @@ bool IndexingContext::handleField(const FieldDecl *D) {
return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
}
+bool IndexingContext::handleMSProperty(const MSPropertyDecl *D) {
+ DeclInfo DInfo(/*isRedeclaration=*/false, /*isDefinition=*/true,
+ /*isContainer=*/false);
+ return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
+}
+
bool IndexingContext::handleEnumerator(const EnumConstantDecl *D) {
DeclInfo DInfo(/*isRedeclaration=*/false, /*isDefinition=*/true,
/*isContainer=*/false);
diff --git a/tools/libclang/IndexingContext.h b/tools/libclang/IndexingContext.h
index c9097c5..62873be 100644
--- a/tools/libclang/IndexingContext.h
+++ b/tools/libclang/IndexingContext.h
@@ -16,6 +16,7 @@
namespace clang {
class FileEntry;
+ class MSPropertyDecl;
class ObjCPropertyDecl;
class ClassTemplateDecl;
class FunctionTemplateDecl;
@@ -404,6 +405,8 @@ public:
bool handleField(const FieldDecl *D);
+ bool handleMSProperty(const MSPropertyDecl *D);
+
bool handleEnumerator(const EnumConstantDecl *D);
bool handleTagDecl(const TagDecl *D);
diff --git a/tools/libclang/RecursiveASTVisitor.h b/tools/libclang/RecursiveASTVisitor.h
index 5862e12..e45545e 100644
--- a/tools/libclang/RecursiveASTVisitor.h
+++ b/tools/libclang/RecursiveASTVisitor.h
@@ -1170,8 +1170,9 @@ bool RecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) {
for (DeclContext::decl_iterator Child = DC->decls_begin(),
ChildEnd = DC->decls_end();
Child != ChildEnd; ++Child) {
- // BlockDecls are traversed through BlockExprs.
- if (!isa<BlockDecl>(*Child))
+ // BlockDecls and CapturedDecls are traversed through BlockExprs and
+ // CapturedStmts respectively.
+ if (!isa<BlockDecl>(*Child) && !isa<CapturedDecl>(*Child))
TRY_TO(TraverseDecl(*Child));
}
@@ -1200,6 +1201,14 @@ DEF_TRAVERSE_DECL(BlockDecl, {
return true;
})
+DEF_TRAVERSE_DECL(CapturedDecl, {
+ TRY_TO(TraverseStmt(D->getBody()));
+ // This return statement makes sure the traversal of nodes in
+ // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
+ // is skipped - don't remove it.
+ return true;
+ })
+
DEF_TRAVERSE_DECL(EmptyDecl, { })
DEF_TRAVERSE_DECL(FileScopeAsmDecl, {
@@ -1614,6 +1623,10 @@ DEF_TRAVERSE_DECL(FieldDecl, {
TRY_TO(TraverseStmt(D->getInClassInitializer()));
})
+DEF_TRAVERSE_DECL(MSPropertyDecl, {
+ TRY_TO(TraverseDeclaratorHelper(D));
+ })
+
DEF_TRAVERSE_DECL(ObjCAtDefsFieldDecl, {
TRY_TO(TraverseDeclaratorHelper(D));
if (D->isBitField())
@@ -1836,7 +1849,6 @@ DEF_TRAVERSE_STMT(ReturnStmt, { })
DEF_TRAVERSE_STMT(SwitchStmt, { })
DEF_TRAVERSE_STMT(WhileStmt, { })
-
DEF_TRAVERSE_STMT(CXXDependentScopeMemberExpr, {
TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
@@ -2079,6 +2091,7 @@ DEF_TRAVERSE_STMT(CompoundLiteralExpr, { })
DEF_TRAVERSE_STMT(CXXBindTemporaryExpr, { })
DEF_TRAVERSE_STMT(CXXBoolLiteralExpr, { })
DEF_TRAVERSE_STMT(CXXDefaultArgExpr, { })
+DEF_TRAVERSE_STMT(CXXDefaultInitExpr, { })
DEF_TRAVERSE_STMT(CXXDeleteExpr, { })
DEF_TRAVERSE_STMT(ExprWithCleanups, { })
DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, { })
@@ -2103,7 +2116,10 @@ DEF_TRAVERSE_STMT(ObjCEncodeExpr, {
})
DEF_TRAVERSE_STMT(ObjCIsaExpr, { })
DEF_TRAVERSE_STMT(ObjCIvarRefExpr, { })
-DEF_TRAVERSE_STMT(ObjCMessageExpr, { })
+DEF_TRAVERSE_STMT(ObjCMessageExpr, {
+ if (TypeSourceInfo *TInfo = S->getClassReceiverTypeInfo())
+ TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
+})
DEF_TRAVERSE_STMT(ObjCPropertyRefExpr, { })
DEF_TRAVERSE_STMT(ObjCSubscriptRefExpr, { })
DEF_TRAVERSE_STMT(ObjCProtocolExpr, { })
@@ -2133,9 +2149,13 @@ DEF_TRAVERSE_STMT(UnresolvedMemberExpr, {
}
})
+DEF_TRAVERSE_STMT(MSPropertyRefExpr, {})
DEF_TRAVERSE_STMT(SEHTryStmt, {})
DEF_TRAVERSE_STMT(SEHExceptStmt, {})
DEF_TRAVERSE_STMT(SEHFinallyStmt,{})
+DEF_TRAVERSE_STMT(CapturedStmt, {
+ TRY_TO(TraverseDecl(S->getCapturedDecl()));
+})
DEF_TRAVERSE_STMT(CXXOperatorCallExpr, { })
DEF_TRAVERSE_STMT(OpaqueValueExpr, { })
diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports
index d99f24e..0c9912e 100644
--- a/tools/libclang/libclang.exports
+++ b/tools/libclang/libclang.exports
@@ -10,13 +10,18 @@ clang_Cursor_getCommentRange
clang_Cursor_getParsedComment
clang_Cursor_getRawCommentText
clang_Cursor_getNumArguments
+clang_Cursor_getObjCDeclQualifiers
+clang_Cursor_getObjCPropertyAttributes
clang_Cursor_getObjCSelectorIndex
clang_Cursor_getSpellingNameRange
clang_Cursor_getTranslationUnit
clang_Cursor_getReceiverType
+clang_Cursor_isBitField
clang_Cursor_isDynamicCall
clang_Cursor_isNull
+clang_Cursor_isVariadic
clang_Cursor_getModule
+clang_Module_getASTFile
clang_Module_getParent
clang_Module_getName
clang_Module_getFullName
@@ -53,6 +58,9 @@ clang_TParamCommandComment_getParamName
clang_TParamCommandComment_isParamPositionValid
clang_TParamCommandComment_getDepth
clang_TParamCommandComment_getIndex
+clang_Type_getAlignOf
+clang_Type_getSizeOf
+clang_Type_getOffsetOf
clang_VerbatimBlockLineComment_getText
clang_VerbatimLineComment_getText
clang_HTMLTagComment_getAsString
@@ -244,6 +252,7 @@ clang_isUnexposed
clang_isVirtualBase
clang_isVolatileQualifiedType
clang_loadDiagnostics
+clang_Location_isInSystemHeader
clang_parseTranslationUnit
clang_remap_dispose
clang_remap_getFilenames
OpenPOWER on IntegriCloud