//===--- AST.h - Utility AST functions -------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // Various code that examines C++ source code using AST. // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_AST_H_ #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_AST_H_ #include "index/SymbolID.h" #include "clang/AST/Decl.h" #include "clang/Basic/SourceLocation.h" #include "clang/Lex/MacroInfo.h" namespace clang { class SourceManager; class Decl; namespace clangd { /// Returns true if the declaration is considered implementation detail based on /// heuristics. For example, a declaration whose name is not explicitly spelled /// in code is considered implementation detail. bool isImplementationDetail(const Decl *D); /// Find the identifier source location of the given D. /// /// The returned location is usually the spelling location where the name of the /// decl occurs in the code. SourceLocation findName(const clang::Decl *D); /// Returns the qualified name of ND. The scope doesn't contain unwritten scopes /// like inline namespaces. std::string printQualifiedName(const NamedDecl &ND); /// Returns the first enclosing namespace scope starting from \p DC. std::string printNamespaceScope(const DeclContext &DC); /// Returns the name of the namespace inside the 'using namespace' directive, as /// written in the code. E.g., passing 'using namespace ::std' will result in /// '::std'. std::string printUsingNamespaceName(const ASTContext &Ctx, const UsingDirectiveDecl &D); /// Prints unqualified name of the decl for the purpose of displaying it to the /// user. Anonymous decls return names of the form "(anonymous {kind})", e.g. /// "(anonymous struct)" or "(anonymous namespace)". std::string printName(const ASTContext &Ctx, const NamedDecl &ND); /// Prints template arguments of a decl as written in the source code, including /// enclosing '<' and '>', e.g for a partial specialization like: template /// struct Foo will return ''. Returns an empty /// string if decl is not a template specialization. std::string printTemplateSpecializationArgs(const NamedDecl &ND); /// Gets the symbol ID for a declaration, if possible. llvm::Optional getSymbolID(const Decl *D); /// Gets the symbol ID for a macro, if possible. /// Currently, this is an encoded USR of the macro, which incorporates macro /// locations (e.g. file name, offset in file). /// FIXME: the USR semantics might not be stable enough as the ID for index /// macro (e.g. a change in definition offset can result in a different USR). We /// could change these semantics in the future by reimplementing this funcure /// (e.g. avoid USR for macros). llvm::Optional getSymbolID(const IdentifierInfo &II, const MacroInfo *MI, const SourceManager &SM); /// Returns a QualType as string. The result doesn't contain unwritten scopes /// like annoymous/inline namespace. std::string printType(const QualType QT, const DeclContext & Context); /// Try to shorten the OriginalName by removing namespaces from the left of /// the string that are redundant in the CurrentNamespace. This way the type /// idenfier become shorter and easier to read. /// Limitation: It only handles the qualifier of the type itself, not that of /// templates. /// FIXME: change type of parameter CurrentNamespace to DeclContext , /// take in to account using directives etc /// Example: shortenNamespace("ns1::MyClass", "ns1") /// --> "MyClass" std::string shortenNamespace(const llvm::StringRef OriginalName, const llvm::StringRef CurrentNamespace); /// Indicates if \p D is a template instantiation implicitly generated by the /// compiler, e.g. /// template struct vector {}; /// vector v; // 'vector' is an implicit instantiation bool isImplicitTemplateInstantiation(const NamedDecl *D); /// Indicates if \p D is an explicit template specialization, e.g. /// template struct vector {}; /// template <> struct vector {}; // <-- explicit specialization /// /// Note that explicit instantiations are NOT explicit specializations, albeit /// they look similar. /// template struct vector; // <-- explicit instantiation, NOT an /// explicit specialization. bool isExplicitTemplateSpecialization(const NamedDecl *D); } // namespace clangd } // namespace clang #endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_AST_H_