diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Index')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Index/CommentToXML.cpp | 64 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Index/SimpleFormatContext.h | 9 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Index/USRGeneration.cpp | 142 |
3 files changed, 138 insertions, 77 deletions
diff --git a/contrib/llvm/tools/clang/lib/Index/CommentToXML.cpp b/contrib/llvm/tools/clang/lib/Index/CommentToXML.cpp index 0a9619d..a67c806 100644 --- a/contrib/llvm/tools/clang/lib/Index/CommentToXML.cpp +++ b/contrib/llvm/tools/clang/lib/Index/CommentToXML.cpp @@ -9,8 +9,8 @@ #include "clang/Index/CommentToXML.h" #include "SimpleFormatContext.h" -#include "clang/AST/Attr.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/Attr.h" #include "clang/AST/Comment.h" #include "clang/AST/CommentVisitor.h" #include "clang/Format/Format.h" @@ -97,7 +97,7 @@ struct FullCommentParts { FullCommentParts::FullCommentParts(const FullComment *C, const CommandTraits &Traits) : - Brief(NULL), Headerfile(NULL), FirstParagraph(NULL) { + Brief(nullptr), Headerfile(nullptr), FirstParagraph(nullptr) { for (Comment::child_iterator I = C->child_begin(), E = C->child_end(); I != E; ++I) { const Comment *Child = *I; @@ -563,6 +563,7 @@ public: // Helpers. void appendToResultWithXMLEscaping(StringRef S); + void appendToResultWithCDATAEscaping(StringRef S); void formatTextOfDeclaration(const DeclInfo *DI, SmallString<128> &Declaration); @@ -667,14 +668,27 @@ void CommentASTToXMLConverter::visitInlineCommandComment( void CommentASTToXMLConverter::visitHTMLStartTagComment( const HTMLStartTagComment *C) { - Result << "<rawHTML><![CDATA["; - printHTMLStartTagComment(C, Result); - Result << "]]></rawHTML>"; + Result << "<rawHTML"; + if (C->isMalformed()) + Result << " isMalformed=\"1\""; + Result << ">"; + { + SmallString<32> Tag; + { + llvm::raw_svector_ostream TagOS(Tag); + printHTMLStartTagComment(C, TagOS); + } + appendToResultWithCDATAEscaping(Tag); + } + Result << "</rawHTML>"; } void CommentASTToXMLConverter::visitHTMLEndTagComment(const HTMLEndTagComment *C) { - Result << "<rawHTML></" << C->getTagName() << "></rawHTML>"; + Result << "<rawHTML"; + if (C->isMalformed()) + Result << " isMalformed=\"1\""; + Result << "></" << C->getTagName() << "></rawHTML>"; } void @@ -1100,6 +1114,31 @@ void CommentASTToXMLConverter::appendToResultWithXMLEscaping(StringRef S) { } } +void CommentASTToXMLConverter::appendToResultWithCDATAEscaping(StringRef S) { + if (S.empty()) + return; + + Result << "<![CDATA["; + while (!S.empty()) { + size_t Pos = S.find("]]>"); + if (Pos == 0) { + Result << "]]]]><![CDATA[>"; + S = S.drop_front(3); + continue; + } + if (Pos == StringRef::npos) + Pos = S.size(); + + Result << S.substr(0, Pos); + + S = S.drop_front(Pos); + } + Result << "]]>"; +} + +CommentToXMLConverter::CommentToXMLConverter() : FormatInMemoryUniqueId(0) {} +CommentToXMLConverter::~CommentToXMLConverter() {} + void CommentToXMLConverter::convertCommentToHTML(const FullComment *FC, SmallVectorImpl<char> &HTML, const ASTContext &Context) { @@ -1111,7 +1150,7 @@ void CommentToXMLConverter::convertCommentToHTML(const FullComment *FC, void CommentToXMLConverter::convertHTMLTagNodeToText( const comments::HTMLTagComment *HTC, SmallVectorImpl<char> &Text, const ASTContext &Context) { - CommentASTToHTMLConverter Converter(0, Text, + CommentASTToHTMLConverter Converter(nullptr, Text, Context.getCommentCommandTraits()); Converter.visit(HTC); } @@ -1119,13 +1158,10 @@ void CommentToXMLConverter::convertHTMLTagNodeToText( void CommentToXMLConverter::convertCommentToXML(const FullComment *FC, SmallVectorImpl<char> &XML, const ASTContext &Context) { - if (!FormatContext) { - FormatContext = new SimpleFormatContext(Context.getLangOpts()); - } else if ((FormatInMemoryUniqueId % 1000) == 0) { - // Delete after some number of iterations, so the buffers don't grow - // too large. - delete FormatContext; - FormatContext = new SimpleFormatContext(Context.getLangOpts()); + if (!FormatContext || (FormatInMemoryUniqueId % 1000) == 0) { + // Create a new format context, or re-create it after some number of + // iterations, so the buffers don't grow too large. + FormatContext.reset(new SimpleFormatContext(Context.getLangOpts())); } CommentASTToXMLConverter Converter(FC, XML, Context.getCommentCommandTraits(), diff --git a/contrib/llvm/tools/clang/lib/Index/SimpleFormatContext.h b/contrib/llvm/tools/clang/lib/Index/SimpleFormatContext.h index fde43ae..a460863 100644 --- a/contrib/llvm/tools/clang/lib/Index/SimpleFormatContext.h +++ b/contrib/llvm/tools/clang/lib/Index/SimpleFormatContext.h @@ -37,7 +37,7 @@ public: SimpleFormatContext(LangOptions Options) : DiagOpts(new DiagnosticOptions()), Diagnostics(new DiagnosticsEngine(new DiagnosticIDs, - DiagOpts.getPtr())), + DiagOpts.get())), Files((FileSystemOptions())), Sources(*Diagnostics, Files), Rewrite(Sources, Options) { @@ -47,12 +47,11 @@ public: ~SimpleFormatContext() { } FileID createInMemoryFile(StringRef Name, StringRef Content) { - const llvm::MemoryBuffer *Source = - llvm::MemoryBuffer::getMemBuffer(Content); + llvm::MemoryBuffer *Source = llvm::MemoryBuffer::getMemBuffer(Content); const FileEntry *Entry = Files.getVirtualFile(Name, Source->getBufferSize(), 0); - Sources.overrideFileContents(Entry, Source, true); - assert(Entry != NULL); + Sources.overrideFileContents(Entry, Source); + assert(Entry != nullptr); return Sources.createFileID(Entry, SourceLocation(), SrcMgr::C_User); } diff --git a/contrib/llvm/tools/clang/lib/Index/USRGeneration.cpp b/contrib/llvm/tools/clang/lib/Index/USRGeneration.cpp index 16d89f8..e08b85e 100644 --- a/contrib/llvm/tools/clang/lib/Index/USRGeneration.cpp +++ b/contrib/llvm/tools/clang/lib/Index/USRGeneration.cpp @@ -11,6 +11,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/DeclVisitor.h" +#include "clang/Lex/PreprocessingRecord.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" @@ -22,6 +23,30 @@ using namespace clang::index; // USR generation. //===----------------------------------------------------------------------===// +/// \returns true on error. +static bool printLoc(llvm::raw_ostream &OS, SourceLocation Loc, + const SourceManager &SM, bool IncludeOffset) { + if (Loc.isInvalid()) { + return true; + } + Loc = SM.getExpansionLoc(Loc); + const std::pair<FileID, unsigned> &Decomposed = SM.getDecomposedLoc(Loc); + const FileEntry *FE = SM.getFileEntryForID(Decomposed.first); + if (FE) { + OS << llvm::sys::path::filename(FE->getName()); + } else { + // This case really isn't interesting. + return true; + } + if (IncludeOffset) { + // Use the offest into the FileID to represent the location. Using + // a line/column can cause us to look back at the original source file, + // which is expensive. + OS << '@' << Decomposed.second; + } + return false; +} + namespace { class USRGenerator : public ConstDeclVisitor<USRGenerator> { SmallVectorImpl<char> &Buf; @@ -80,10 +105,16 @@ public: void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D) { IgnoreResults = true; } - + + bool ShouldGenerateLocation(const NamedDecl *D); + + bool isLocal(const NamedDecl *D) { + return D->getParentFunctionOrMethod() != nullptr; + } + /// Generate the string component containing the location of the /// declaration. - bool GenLoc(const Decl *D); + bool GenLoc(const Decl *D, bool IncludeOffset); /// String generation methods used both by the visitation methods /// and from other clients that want to directly generate USRs. These @@ -99,16 +130,6 @@ public: void GenObjCCategory(StringRef cls, StringRef cat) { generateUSRForObjCCategory(cls, cat, Out); } - /// Generate a USR fragment for an Objective-C instance variable. The - /// complete USR can be created by concatenating the USR for the - /// encompassing class with this USR fragment. - void GenObjCIvar(StringRef ivar) { - generateUSRForObjCIvar(ivar, Out); - } - /// Generate a USR fragment for an Objective-C method. - void GenObjCMethod(StringRef sel, bool isInstanceMethod) { - generateUSRForObjCMethod(sel, isInstanceMethod, Out); - } /// Generate a USR fragment for an Objective-C property. void GenObjCProperty(StringRef prop) { generateUSRForObjCProperty(prop, Out); @@ -143,8 +164,13 @@ bool USRGenerator::EmitDeclName(const NamedDecl *D) { return startSize == endSize; } -static inline bool ShouldGenerateLocation(const NamedDecl *D) { - return !D->isExternallyVisible(); +bool USRGenerator::ShouldGenerateLocation(const NamedDecl *D) { + if (D->isExternallyVisible()) + return false; + if (D->getParentFunctionOrMethod()) + return true; + const SourceManager &SM = Context->getSourceManager(); + return !SM.isInSystemHeader(D->getLocation()); } void USRGenerator::VisitDeclContext(const DeclContext *DC) { @@ -168,7 +194,7 @@ void USRGenerator::VisitFieldDecl(const FieldDecl *D) { } void USRGenerator::VisitFunctionDecl(const FunctionDecl *D) { - if (ShouldGenerateLocation(D) && GenLoc(D)) + if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D))) return; VisitDeclContext(D->getDeclContext()); @@ -194,12 +220,9 @@ void USRGenerator::VisitFunctionDecl(const FunctionDecl *D) { } // Mangle in type information for the arguments. - for (FunctionDecl::param_const_iterator I = D->param_begin(), - E = D->param_end(); - I != E; ++I) { + for (auto PD : D->params()) { Out << '#'; - if (ParmVarDecl *PD = *I) - VisitType(PD->getType()); + VisitType(PD->getType()); } if (D->isVariadic()) Out << '.'; @@ -229,7 +252,7 @@ void USRGenerator::VisitVarDecl(const VarDecl *D) { // VarDecls can be declared 'extern' within a function or method body, // but their enclosing DeclContext is the function, not the TU. We need // to check the storage class to correctly generate the USR. - if (ShouldGenerateLocation(D) && GenLoc(D)) + if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D))) return; VisitDeclContext(D->getDeclContext()); @@ -249,13 +272,13 @@ void USRGenerator::VisitVarDecl(const VarDecl *D) { void USRGenerator::VisitNonTypeTemplateParmDecl( const NonTypeTemplateParmDecl *D) { - GenLoc(D); + GenLoc(D, /*IncludeOffset=*/true); return; } void USRGenerator::VisitTemplateTemplateParmDecl( const TemplateTemplateParmDecl *D) { - GenLoc(D); + GenLoc(D, /*IncludeOffset=*/true); return; } @@ -329,7 +352,7 @@ void USRGenerator::VisitObjCContainerDecl(const ObjCContainerDecl *D) { // We want to mangle in the location to uniquely distinguish them. if (CD->IsClassExtension()) { Out << "objc(ext)" << ID->getName() << '@'; - GenLoc(CD); + GenLoc(CD, /*IncludeOffset=*/true); } else GenObjCCategory(ID->getName(), CD->getName()); @@ -378,7 +401,7 @@ void USRGenerator::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) { void USRGenerator::VisitTagDecl(const TagDecl *D) { // Add the location of the tag decl to handle resolution across // translation units. - if (ShouldGenerateLocation(D) && GenLoc(D)) + if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D))) return; D = D->getCanonicalDecl(); @@ -449,7 +472,7 @@ void USRGenerator::VisitTagDecl(const TagDecl *D) { } void USRGenerator::VisitTypedefDecl(const TypedefDecl *D) { - if (ShouldGenerateLocation(D) && GenLoc(D)) + if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D))) return; const DeclContext *DC = D->getDeclContext(); if (const NamedDecl *DCN = dyn_cast<NamedDecl>(DC)) @@ -459,15 +482,15 @@ void USRGenerator::VisitTypedefDecl(const TypedefDecl *D) { } void USRGenerator::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) { - GenLoc(D); + GenLoc(D, /*IncludeOffset=*/true); return; } -bool USRGenerator::GenLoc(const Decl *D) { +bool USRGenerator::GenLoc(const Decl *D, bool IncludeOffset) { if (generatedLoc) return IgnoreResults; generatedLoc = true; - + // Guard against null declarations in invalid code. if (!D) { IgnoreResults = true; @@ -477,27 +500,10 @@ bool USRGenerator::GenLoc(const Decl *D) { // Use the location of canonical decl. D = D->getCanonicalDecl(); - const SourceManager &SM = Context->getSourceManager(); - SourceLocation L = D->getLocStart(); - if (L.isInvalid()) { - IgnoreResults = true; - return true; - } - L = SM.getExpansionLoc(L); - const std::pair<FileID, unsigned> &Decomposed = SM.getDecomposedLoc(L); - const FileEntry *FE = SM.getFileEntryForID(Decomposed.first); - if (FE) { - Out << llvm::sys::path::filename(FE->getName()); - } - else { - // This case really isn't interesting. - IgnoreResults = true; - return true; - } - // Use the offest into the FileID to represent the location. Using - // a line/column can cause us to look back at the original source file, - // which is expensive. - Out << '@' << Decomposed.second; + IgnoreResults = + IgnoreResults || printLoc(Out, D->getLocStart(), + Context->getSourceManager(), IncludeOffset); + return IgnoreResults; } @@ -627,11 +633,9 @@ void USRGenerator::VisitType(QualType T) { } if (const FunctionProtoType *FT = T->getAs<FunctionProtoType>()) { Out << 'F'; - VisitType(FT->getResultType()); - for (FunctionProtoType::arg_type_iterator - I = FT->arg_type_begin(), E = FT->arg_type_end(); I!=E; ++I) { - VisitType(*I); - } + VisitType(FT->getReturnType()); + for (const auto &I : FT->param_types()) + VisitType(I); if (FT->isVariadic()) Out << '.'; return; @@ -743,9 +747,8 @@ void USRGenerator::VisitTemplateArgument(const TemplateArgument &Arg) { case TemplateArgument::Pack: Out << 'p' << Arg.pack_size(); - for (TemplateArgument::pack_iterator P = Arg.pack_begin(), PEnd = Arg.pack_end(); - P != PEnd; ++P) - VisitTemplateArgument(*P); + for (const auto &P : Arg.pack_elements()) + VisitTemplateArgument(P); break; case TemplateArgument::Type: @@ -801,3 +804,26 @@ bool clang::index::generateUSRForDecl(const Decl *D, UG.Visit(D); return UG.ignoreResults(); } + +bool clang::index::generateUSRForMacro(const MacroDefinition *MD, + const SourceManager &SM, + SmallVectorImpl<char> &Buf) { + // Don't generate USRs for things with invalid locations. + if (!MD || MD->getLocation().isInvalid()) + return true; + + llvm::raw_svector_ostream Out(Buf); + + // Assume that system headers are sane. Don't put source location + // information into the USR if the macro comes from a system header. + SourceLocation Loc = MD->getLocation(); + bool ShouldGenerateLocation = !SM.isInSystemHeader(Loc); + + Out << getUSRSpacePrefix(); + if (ShouldGenerateLocation) + printLoc(Out, Loc, SM, /*IncludeOffset=*/true); + Out << "@macro@"; + Out << MD->getName()->getName(); + return false; +} + |