diff options
Diffstat (limited to 'tools/libclang/CIndex.cpp')
-rw-r--r-- | tools/libclang/CIndex.cpp | 318 |
1 files changed, 235 insertions, 83 deletions
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index a43c1ab..f53e5c1 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -22,13 +22,14 @@ #include "CXTranslationUnit.h" #include "CXType.h" #include "CursorVisitor.h" -#include "SimpleFormatContext.h" +#include "clang/AST/Attr.h" #include "clang/AST/StmtVisitor.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/Version.h" #include "clang/Frontend/ASTUnit.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendDiagnostic.h" +#include "clang/Index/CommentToXML.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/Lexer.h" #include "clang/Lex/PreprocessingRecord.h" @@ -42,7 +43,6 @@ #include "llvm/Support/Format.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Mutex.h" -#include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Program.h" #include "llvm/Support/SaveAndRestore.h" #include "llvm/Support/Signals.h" @@ -68,8 +68,7 @@ CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) { D->StringPool = new cxstring::CXStringPool(); D->Diagnostics = 0; D->OverridenCursorsPool = createOverridenCXCursorsPool(); - D->FormatContext = 0; - D->FormatInMemoryUniqueId = 0; + D->CommentToXML = 0; return D; } @@ -308,8 +307,8 @@ bool CursorVisitor::visitDeclsFromFileRegion(FileID File, bool VisitedAtLeastOnce = false; DeclContext *CurDC = 0; - SmallVector<Decl *, 16>::iterator DIt = Decls.begin(); - for (SmallVector<Decl *, 16>::iterator DE = Decls.end(); DIt != DE; ++DIt) { + SmallVectorImpl<Decl *>::iterator DIt = Decls.begin(); + for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) { Decl *D = *DIt; if (D->getSourceRange().isInvalid()) continue; @@ -426,6 +425,9 @@ bool CursorVisitor::visitPreprocessedEntities(InputIterator First, continue; PreprocessedEntity *PPE = *First; + if (!PPE) + continue; + if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) { if (Visit(MakeMacroExpansionCursor(ME, TU))) return true; @@ -528,9 +530,10 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) { if (Cursor.kind == CXCursor_IBOutletCollectionAttr) { const IBOutletCollectionAttr *A = cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor)); - if (const ObjCInterfaceType *InterT = A->getInterface()->getAs<ObjCInterfaceType>()) - return Visit(cxcursor::MakeCursorObjCClassRef(InterT->getInterface(), - A->getInterfaceLoc(), TU)); + if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>()) + return Visit(cxcursor::MakeCursorObjCClassRef( + ObjT->getInterface(), + A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU)); } // If pointing inside a macro definition, check if the token is an identifier @@ -698,8 +701,9 @@ bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl( return true; // Visit the partial specialization arguments. - const TemplateArgumentLoc *TemplateArgs = D->getTemplateArgsAsWritten(); - for (unsigned I = 0, N = D->getNumTemplateArgsAsWritten(); I != N; ++I) + const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten(); + const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs(); + for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I) if (VisitTemplateArgumentLoc(TemplateArgs[I])) return true; @@ -743,18 +747,9 @@ bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) { } /// \brief Compare two base or member initializers based on their source order. -static int CompareCXXCtorInitializers(const void* Xp, const void *Yp) { - CXXCtorInitializer const * const *X - = static_cast<CXXCtorInitializer const * const *>(Xp); - CXXCtorInitializer const * const *Y - = static_cast<CXXCtorInitializer const * const *>(Yp); - - if ((*X)->getSourceOrder() < (*Y)->getSourceOrder()) - return -1; - else if ((*X)->getSourceOrder() > (*Y)->getSourceOrder()) - return 1; - else - return 0; +static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X, + CXXCtorInitializer *const *Y) { + return (*X)->getSourceOrder() - (*Y)->getSourceOrder(); } bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) { @@ -1543,6 +1538,10 @@ bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) { return false; } +bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) { + return Visit(TL.getOriginalLoc()); +} + bool CursorVisitor::VisitTemplateSpecializationTypeLoc( TemplateSpecializationTypeLoc TL) { // Visit the template name. @@ -1795,6 +1794,7 @@ public: } }; class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> { + friend class OMPClauseEnqueue; VisitorWorkList &WL; CXCursor Parent; public: @@ -1846,6 +1846,8 @@ public: void VisitPseudoObjectExpr(const PseudoObjectExpr *E); void VisitOpaqueValueExpr(const OpaqueValueExpr *E); void VisitLambdaExpr(const LambdaExpr *E); + void VisitOMPExecutableDirective(const OMPExecutableDirective *D); + void VisitOMPParallelDirective(const OMPParallelDirective *D); private: void AddDeclarationNameInfo(const Stmt *S); @@ -1856,6 +1858,7 @@ private: void AddDecl(const Decl *D, bool isFirst = true); void AddTypeLoc(TypeSourceInfo *TI); void EnqueueChildren(const Stmt *S); + void EnqueueChildren(const OMPClause *S); }; } // end anonyous namespace @@ -1904,6 +1907,52 @@ void EnqueueVisitor::EnqueueChildren(const Stmt *S) { VisitorWorkList::iterator I = WL.begin() + size, E = WL.end(); std::reverse(I, E); } +namespace { +class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> { + EnqueueVisitor *Visitor; + /// \brief Process clauses with list of variables. + template <typename T> + void VisitOMPClauseList(T *Node); +public: + OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { } +#define OPENMP_CLAUSE(Name, Class) \ + void Visit##Class(const Class *C); +#include "clang/Basic/OpenMPKinds.def" +}; + +void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { } + +template<typename T> +void OMPClauseEnqueue::VisitOMPClauseList(T *Node) { + for (typename T::varlist_const_iterator I = Node->varlist_begin(), + E = Node->varlist_end(); + I != E; ++I) + Visitor->AddStmt(*I); +} + +void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) { + VisitOMPClauseList(C); +} +void OMPClauseEnqueue::VisitOMPFirstprivateClause( + const OMPFirstprivateClause *C) { + VisitOMPClauseList(C); +} +void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) { + VisitOMPClauseList(C); +} +} + +void EnqueueVisitor::EnqueueChildren(const OMPClause *S) { + unsigned size = WL.size(); + OMPClauseEnqueue Visitor(this); + Visitor.Visit(S); + if (size == WL.size()) + return; + // Now reverse the entries we just added. This will match the DFS + // ordering performed by the worklist. + VisitorWorkList::iterator I = WL.begin() + size, E = WL.end(); + std::reverse(I, E); +} void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) { WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent)); } @@ -2027,7 +2076,6 @@ void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) { } void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) { AddStmt(E->getInit()); - typedef DesignatedInitExpr::Designator Designator; for (DesignatedInitExpr::const_reverse_designators_iterator D = E->designators_rbegin(), DEnd = E->designators_rend(); D != DEnd; ++D) { @@ -2182,6 +2230,19 @@ void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) { Visit(E->getSyntacticForm()); } +void EnqueueVisitor::VisitOMPExecutableDirective( + const OMPExecutableDirective *D) { + EnqueueChildren(D); + for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(), + E = D->clauses().end(); + I != E; ++I) + EnqueueChildren(*I); +} + +void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) { + VisitOMPExecutableDirective(D); +} + void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) { EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S); } @@ -2198,8 +2259,7 @@ bool CursorVisitor::IsInRegionOfInterest(CXCursor C) { bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) { while (!WL.empty()) { // Dequeue the worklist item. - VisitorJob LI = WL.back(); - WL.pop_back(); + VisitorJob LI = WL.pop_back_val(); // Set the Parent field, then back to its old value once we're done. SetParentRAII SetParent(Parent, StmtParent, LI.getParent()); @@ -2363,9 +2423,10 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) { for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(), CEnd = E->explicit_capture_end(); C != CEnd; ++C) { - if (C->capturesThis()) + // FIXME: Lambda init-captures. + if (!C->capturesVariable()) continue; - + if (Visit(MakeCursorVariableRef(C->getCapturedVar(), C->getLocation(), TU))) @@ -2481,10 +2542,6 @@ static void fatal_error_handler(void *user_data, const std::string& reason, extern "C" { CXIndex clang_createIndex(int excludeDeclarationsFromPCH, int displayDiagnostics) { - // Disable pretty stack trace functionality, which will otherwise be a very - // poor citizen of the world and set up all sorts of signal handlers. - llvm::DisablePrettyStackTrace = true; - // We use crash recovery to make some of our APIs more reliable, implicitly // enable it. llvm::CrashRecoveryContext::Enable(); @@ -2540,9 +2597,13 @@ void clang_toggleCrashRecovery(unsigned isEnabled) { CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx, const char *ast_filename) { - if (!CIdx) + if (!CIdx || !ast_filename) return 0; + LOG_FUNC_SECTION { + *Log << ast_filename; + } + CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx); FileSystemOptions FileSystemOpts; @@ -2842,7 +2903,7 @@ void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) { delete CTUnit->StringPool; delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics); disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool); - delete CTUnit->FormatContext; + delete CTUnit->CommentToXML; delete CTUnit; } } @@ -2995,15 +3056,12 @@ int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) { if (!file || !outID) return 1; -#ifdef LLVM_ON_WIN32 - return 1; // inodes not supported on windows. -#else FileEntry *FEnt = static_cast<FileEntry *>(file); - outID->data[0] = FEnt->getDevice(); - outID->data[1] = FEnt->getInode(); + const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID(); + outID->data[0] = ID.getDevice(); + outID->data[1] = ID.getFile(); outID->data[2] = FEnt->getModificationTime(); return 0; -#endif } } // end: extern "C" @@ -3289,6 +3347,10 @@ CXString clang_getCursorSpelling(CXCursor C) { return cxstring::createDup(AA->getLabel()); } + if (C.kind == CXCursor_PackedAttr) { + return cxstring::createRef("packed"); + } + return cxstring::createEmpty(); } @@ -3706,6 +3768,8 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) { return cxstring::createRef("attribute(annotate)"); case CXCursor_AsmLabelAttr: return cxstring::createRef("asm label"); + case CXCursor_PackedAttr: + return cxstring::createRef("attribute(packed)"); case CXCursor_PreprocessingDirective: return cxstring::createRef("preprocessing directive"); case CXCursor_MacroDefinition: @@ -3754,6 +3818,8 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) { return cxstring::createRef("CXXAccessSpecifier"); case CXCursor_ModuleImportDecl: return cxstring::createRef("ModuleImport"); + case CXCursor_OMPParallelDirective: + return cxstring::createRef("OMPParallelDirective"); } llvm_unreachable("Unhandled CXCursorKind"); @@ -4111,6 +4177,12 @@ CXSourceLocation clang_getCursorLocation(CXCursor C) { return cxloc::translateSourceLocation(getCursorContext(C), L); } + if (clang_isAttribute(C.kind)) { + SourceLocation L + = cxcursor::getCursorAttr(C)->getLocation(); + return cxloc::translateSourceLocation(getCursorContext(C), L); + } + if (!clang_isDeclaration(C.kind)) return clang_getNullLocation(); @@ -4521,7 +4593,9 @@ CXCursor clang_getCursorDefinition(CXCursor C) { return clang_getNullCursor(); } - case Decl::Var: { + case Decl::Var: + case Decl::VarTemplateSpecialization: + case Decl::VarTemplatePartialSpecialization: { // Ask the variable if it has a definition. if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition()) return MakeCXCursor(Def, TU); @@ -4543,6 +4617,13 @@ CXCursor clang_getCursorDefinition(CXCursor C) { return clang_getNullCursor(); } + case Decl::VarTemplate: { + if (VarDecl *Def = + cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition()) + return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU); + return clang_getNullCursor(); + } + case Decl::Using: return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D), D->getLocation(), TU); @@ -5171,6 +5252,11 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) { HasContextSensitiveKeywords = true; } } + + // Don't override a property annotation with its getter/setter method. + if (cursor.kind == CXCursor_ObjCInstanceMethodDecl && + parent.kind == CXCursor_ObjCPropertyDecl) + return CXChildVisit_Continue; if (clang_isPreprocessing(cursor.kind)) { // Items in the preprocessing record are kept separate from items in @@ -5678,8 +5764,9 @@ CXLinkageKind clang_getCursorLinkage(CXCursor cursor) { const Decl *D = cxcursor::getCursorDecl(cursor); if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D)) - switch (ND->getLinkage()) { - case NoLinkage: return CXLinkage_NoLinkage; + switch (ND->getLinkageInternal()) { + case NoLinkage: + case VisibleNoLinkage: return CXLinkage_NoLinkage; case InternalLinkage: return CXLinkage_Internal; case UniqueExternalLinkage: return CXLinkage_UniqueExternal; case ExternalLinkage: return CXLinkage_External; @@ -5743,25 +5830,33 @@ static CXLanguageKind getDeclLanguage(const Decl *D) { } extern "C" { + +static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) { + if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted()) + return CXAvailability_Available; -enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) { - if (clang_isDeclaration(cursor.kind)) - if (const Decl *D = cxcursor::getCursorDecl(cursor)) { - if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted()) - return CXAvailability_Available; - - switch (D->getAvailability()) { - case AR_Available: - case AR_NotYetIntroduced: - return CXAvailability_Available; + switch (D->getAvailability()) { + case AR_Available: + case AR_NotYetIntroduced: + if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D)) + return getCursorAvailabilityForDecl( + cast<Decl>(EnumConst->getDeclContext())); + return CXAvailability_Available; - case AR_Deprecated: - return CXAvailability_Deprecated; + case AR_Deprecated: + return CXAvailability_Deprecated; - case AR_Unavailable: - return CXAvailability_NotAvailable; - } - } + case AR_Unavailable: + return CXAvailability_NotAvailable; + } + + llvm_unreachable("Unknown availability kind!"); +} + +enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) { + if (clang_isDeclaration(cursor.kind)) + if (const Decl *D = cxcursor::getCursorDecl(cursor)) + return getCursorAvailabilityForDecl(D); return CXAvailability_Available; } @@ -5785,34 +5880,20 @@ static CXVersion convertVersion(VersionTuple In) { return Out; } - -int clang_getCursorPlatformAvailability(CXCursor cursor, - int *always_deprecated, - CXString *deprecated_message, - int *always_unavailable, - CXString *unavailable_message, - CXPlatformAvailability *availability, - int availability_size) { - if (always_deprecated) - *always_deprecated = 0; - if (deprecated_message) - *deprecated_message = cxstring::createEmpty(); - if (always_unavailable) - *always_unavailable = 0; - if (unavailable_message) - *unavailable_message = cxstring::createEmpty(); - - if (!clang_isDeclaration(cursor.kind)) - return 0; - - const Decl *D = cxcursor::getCursorDecl(cursor); - if (!D) - return 0; - + +static int getCursorPlatformAvailabilityForDecl(const Decl *D, + int *always_deprecated, + CXString *deprecated_message, + int *always_unavailable, + CXString *unavailable_message, + CXPlatformAvailability *availability, + int availability_size) { + bool HadAvailAttr = false; int N = 0; for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd; ++A) { if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) { + HadAvailAttr = true; if (always_deprecated) *always_deprecated = 1; if (deprecated_message) @@ -5821,6 +5902,7 @@ int clang_getCursorPlatformAvailability(CXCursor cursor, } if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) { + HadAvailAttr = true; if (always_unavailable) *always_unavailable = 1; if (unavailable_message) { @@ -5830,6 +5912,7 @@ int clang_getCursorPlatformAvailability(CXCursor cursor, } if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) { + HadAvailAttr = true; if (N < availability_size) { availability[N].Platform = cxstring::createDup(Avail->getPlatform()->getName()); @@ -5842,9 +5925,51 @@ int clang_getCursorPlatformAvailability(CXCursor cursor, ++N; } } + + if (!HadAvailAttr) + if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D)) + return getCursorPlatformAvailabilityForDecl( + cast<Decl>(EnumConst->getDeclContext()), + always_deprecated, + deprecated_message, + always_unavailable, + unavailable_message, + availability, + availability_size); return N; } + +int clang_getCursorPlatformAvailability(CXCursor cursor, + int *always_deprecated, + CXString *deprecated_message, + int *always_unavailable, + CXString *unavailable_message, + CXPlatformAvailability *availability, + int availability_size) { + if (always_deprecated) + *always_deprecated = 0; + if (deprecated_message) + *deprecated_message = cxstring::createEmpty(); + if (always_unavailable) + *always_unavailable = 0; + if (unavailable_message) + *unavailable_message = cxstring::createEmpty(); + + if (!clang_isDeclaration(cursor.kind)) + return 0; + + const Decl *D = cxcursor::getCursorDecl(cursor); + if (!D) + return 0; + + return getCursorPlatformAvailabilityForDecl(D, always_deprecated, + deprecated_message, + always_unavailable, + unavailable_message, + availability, + availability_size); +} void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) { clang_disposeString(availability->Platform); @@ -5974,6 +6099,19 @@ unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) { return Result; } +unsigned clang_Cursor_isObjCOptional(CXCursor C) { + if (!clang_isDeclaration(C.kind)) + return 0; + + const Decl *D = getCursorDecl(C); + if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D)) + return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional; + if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) + return MD->getImplementationControl() == ObjCMethodDecl::Optional; + + return 0; +} + unsigned clang_Cursor_isVariadic(CXCursor C) { if (!clang_isDeclaration(C.kind)) return 0; @@ -6114,6 +6252,20 @@ CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU, //===----------------------------------------------------------------------===// extern "C" { +unsigned clang_CXXMethod_isPureVirtual(CXCursor C) { + if (!clang_isDeclaration(C.kind)) + return 0; + + const CXXMethodDecl *Method = 0; + const Decl *D = cxcursor::getCursorDecl(C); + if (const FunctionTemplateDecl *FunTmpl = + dyn_cast_or_null<FunctionTemplateDecl>(D)) + Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl()); + else + Method = dyn_cast_or_null<CXXMethodDecl>(D); + return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0; +} + unsigned clang_CXXMethod_isStatic(CXCursor C) { if (!clang_isDeclaration(C.kind)) return 0; |