diff --git a/docs/ClangFormatStyleOptions.rst b/docs/ClangFormatStyleOptions.rst index bfabd5985c..1e9a3723d1 100644 --- a/docs/ClangFormatStyleOptions.rst +++ b/docs/ClangFormatStyleOptions.rst @@ -666,7 +666,7 @@ Adding additional style options =============================== Each additional style option adds costs to the clang-format project. Some of -these costs affect the clang-format developement itself, as we need to make +these costs affect the clang-format development itself, as we need to make sure that any given combination of options work and that new features don't break any of the existing options in any way. There are also costs for end users as options become less discoverable and people have to think about and make a diff --git a/docs/CrossCompilation.rst b/docs/CrossCompilation.rst index 8a80271173..c07bc21a43 100644 --- a/docs/CrossCompilation.rst +++ b/docs/CrossCompilation.rst @@ -32,7 +32,7 @@ when compiling your code. On the other hand, Clang/LLVM is natively a cross-compiler, meaning that one set of programs can compile to all targets by setting the ``-target`` -option. That makes it a lot easier for programers wishing to compile to +option. That makes it a lot easier for programmers wishing to compile to different platforms and architectures, and for compiler developers that only have to maintain one build system, and for OS distributions, that need only one set of main packages. diff --git a/docs/LanguageExtensions.rst b/docs/LanguageExtensions.rst index 333dee618c..2dbf223d68 100644 --- a/docs/LanguageExtensions.rst +++ b/docs/LanguageExtensions.rst @@ -1857,7 +1857,7 @@ in the `ARM C Language Extensions Release 2.0 `_. Note that these intrinsics are implemented as motion barriers that block reordering of memory accesses and side effect instructions. Other instructions -like simple arithmatic may be reordered around the intrinsic. If you expect to +like simple arithmetic may be reordered around the intrinsic. If you expect to have no reordering at all, use inline assembly instead. X86/X86-64 Language Extensions diff --git a/docs/SanitizerCoverage.rst b/docs/SanitizerCoverage.rst index 371efc4e78..0e493400b4 100644 --- a/docs/SanitizerCoverage.rst +++ b/docs/SanitizerCoverage.rst @@ -110,8 +110,8 @@ Sancov matches these files using module names and binaries file names. Action (required) -print - Print coverage addresses - -covered-functions - Print all covered funcions. - -not-covered-functions - Print all not covered funcions. + -covered-functions - Print all covered functions. + -not-covered-functions - Print all not covered functions. -html-report - Print HTML coverage report. Options diff --git a/include/clang/AST/Mangle.h b/include/clang/AST/Mangle.h index bf4b23c267..d489746b40 100644 --- a/include/clang/AST/Mangle.h +++ b/include/clang/AST/Mangle.h @@ -124,6 +124,7 @@ public: void mangleBlock(const DeclContext *DC, const BlockDecl *BD, raw_ostream &Out); + void mangleObjCMethodNameWithoutSize(const ObjCMethodDecl *MD, raw_ostream &); void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &); virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) = 0; diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h index 8ab3f61703..57495efa96 100644 --- a/include/clang/AST/PrettyPrinter.h +++ b/include/clang/AST/PrettyPrinter.h @@ -40,6 +40,7 @@ struct PrintingPolicy { SuppressUnwrittenScope(false), SuppressInitializers(false), ConstantArraySizeAsWritten(false), AnonymousTagLocations(true), SuppressStrongLifetime(false), SuppressLifetimeQualifiers(false), + SuppressTemplateArgsInCXXConstructors(false), Bool(LO.Bool), TerseOutput(false), PolishForDeclaration(false), Half(LO.Half), MSWChar(LO.MicrosoftExt && !LO.WChar), IncludeNewlines(true), MSVCFormatting(false) { } @@ -136,7 +137,11 @@ struct PrintingPolicy { /// \brief When true, suppress printing of lifetime qualifier in /// ARC. unsigned SuppressLifetimeQualifiers : 1; - + + /// When true, suppresses printing template arguments in names of C++ + /// constructors. + unsigned SuppressTemplateArgsInCXXConstructors : 1; + /// \brief Whether we can use 'bool' rather than '_Bool', even if the language /// doesn't actually have 'bool' (because, e.g., it is defined as a macro). unsigned Bool : 1; diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h index 5192ac3c98..92fcced9d8 100644 --- a/include/clang/ASTMatchers/ASTMatchers.h +++ b/include/clang/ASTMatchers/ASTMatchers.h @@ -3673,6 +3673,19 @@ AST_MATCHER(QualType, isAnyCharacter) { return Node->isAnyCharacterType(); } +//// \brief Matches QualType nodes that are of any pointer type. +/// +/// Given +/// \code +/// int *i = nullptr; +/// int j; +/// \endcode +/// varDecl(hasType(isAnyPointer())) +/// matches "int *i", but not "int j". +AST_MATCHER(QualType, isAnyPointer) { + return Node->isAnyPointerType(); +} + /// \brief Matches QualType nodes that are const-qualified, i.e., that /// include "top-level" const. /// diff --git a/include/clang/Index/CodegenNameGenerator.h b/include/clang/Index/CodegenNameGenerator.h new file mode 100644 index 0000000000..e8dc196a20 --- /dev/null +++ b/include/clang/Index/CodegenNameGenerator.h @@ -0,0 +1,52 @@ +//===- CodegenNameGenerator.h - Codegen name generation -------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Determines the name that the symbol will get for code generation. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_INDEX_CODEGENNAMEGENERATOR_H +#define LLVM_CLANG_INDEX_CODEGENNAMEGENERATOR_H + +#include "clang/Basic/LLVM.h" +#include +#include +#include + +namespace clang { + class ASTContext; + class Decl; + +namespace index { + +class CodegenNameGenerator { +public: + explicit CodegenNameGenerator(ASTContext &Ctx); + ~CodegenNameGenerator(); + + /// \returns true on failure to produce a name for the given decl, false on + /// success. + bool writeName(const Decl *D, raw_ostream &OS); + + /// Version of \c writeName function that returns a string. + std::string getName(const Decl *D); + + /// This can return multiple mangled names when applicable, e.g. for C++ + /// constructors/destructors. + std::vector getAllManglings(const Decl *D); + +private: + struct Implementation; + std::unique_ptr Impl; +}; + +} // namespace index +} // namespace clang + +#endif // LLVM_CLANG_INDEX_CODEGENNAMEGENERATOR_H diff --git a/include/clang/Index/IndexDataConsumer.h b/include/clang/Index/IndexDataConsumer.h index cb00345f56..3154370483 100644 --- a/include/clang/Index/IndexDataConsumer.h +++ b/include/clang/Index/IndexDataConsumer.h @@ -13,6 +13,7 @@ #include "clang/Index/IndexSymbol.h" namespace clang { + class ASTContext; class DeclContext; class Expr; class FileID; @@ -33,6 +34,8 @@ public: virtual ~IndexDataConsumer() {} + virtual void initialize(ASTContext &Ctx) {} + /// \returns true to continue indexing, or false to abort. virtual bool handleDeclOccurence(const Decl *D, SymbolRoleSet Roles, ArrayRef Relations, diff --git a/include/clang/Index/IndexSymbol.h b/include/clang/Index/IndexSymbol.h index feee13cdbf..506540b0e6 100644 --- a/include/clang/Index/IndexSymbol.h +++ b/include/clang/Index/IndexSymbol.h @@ -16,6 +16,7 @@ namespace clang { class Decl; + class LangOptions; namespace index { @@ -111,6 +112,10 @@ SymbolInfo getSymbolInfo(const Decl *D); void applyForEachSymbolRole(SymbolRoleSet Roles, llvm::function_ref Fn); void printSymbolRoles(SymbolRoleSet Roles, raw_ostream &OS); + +/// \returns true if no name was printed, false otherwise. +bool printSymbolName(const Decl *D, const LangOptions &LO, raw_ostream &OS); + StringRef getSymbolKindString(SymbolKind K); StringRef getTemplateKindStr(SymbolCXXTemplateKind TK); StringRef getSymbolLanguageString(SymbolLanguage K); diff --git a/lib/AST/DeclarationName.cpp b/lib/AST/DeclarationName.cpp index f6d045b2da..344a238922 100644 --- a/lib/AST/DeclarationName.cpp +++ b/lib/AST/DeclarationName.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// #include "clang/AST/ASTContext.h" -#include "clang/AST/Decl.h" +#include "clang/AST/DeclCXX.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/Type.h" #include "clang/AST/TypeLoc.h" @@ -140,6 +140,12 @@ static void printCXXConstructorDestructorName(QualType ClassType, OS << *ClassRec->getDecl(); return; } + if (Policy.SuppressTemplateArgsInCXXConstructors) { + if (auto *InjTy = ClassType->getAs()) { + OS << *InjTy->getDecl(); + return; + } + } if (!Policy.LangOpts.CPlusPlus) { // Passed policy is the default one from operator <<, use a C++ policy. LangOptions LO; diff --git a/lib/AST/Mangle.cpp b/lib/AST/Mangle.cpp index b1193ca2d2..7a9cf18acc 100644 --- a/lib/AST/Mangle.cpp +++ b/lib/AST/Mangle.cpp @@ -254,11 +254,8 @@ void MangleContext::mangleBlock(const DeclContext *DC, const BlockDecl *BD, mangleFunctionBlock(*this, Buffer, BD, Out); } -void MangleContext::mangleObjCMethodName(const ObjCMethodDecl *MD, - raw_ostream &Out) { - SmallString<64> Name; - llvm::raw_svector_ostream OS(Name); - +void MangleContext::mangleObjCMethodNameWithoutSize(const ObjCMethodDecl *MD, + raw_ostream &OS) { const ObjCContainerDecl *CD = dyn_cast(MD->getDeclContext()); assert (CD && "Missing container decl in GetNameForMethod"); @@ -268,6 +265,13 @@ void MangleContext::mangleObjCMethodName(const ObjCMethodDecl *MD, OS << ' '; MD->getSelector().print(OS); OS << ']'; - +} + +void MangleContext::mangleObjCMethodName(const ObjCMethodDecl *MD, + raw_ostream &Out) { + SmallString<64> Name; + llvm::raw_svector_ostream OS(Name); + + mangleObjCMethodNameWithoutSize(MD, OS); Out << OS.str().size() << OS.str(); } diff --git a/lib/ASTMatchers/Dynamic/Registry.cpp b/lib/ASTMatchers/Dynamic/Registry.cpp index 8948d18e8f..e69688c5a6 100644 --- a/lib/ASTMatchers/Dynamic/Registry.cpp +++ b/lib/ASTMatchers/Dynamic/Registry.cpp @@ -264,6 +264,8 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(innerType); REGISTER_MATCHER(integerLiteral); REGISTER_MATCHER(isAnonymous); + REGISTER_MATCHER(isAnyCharacter); + REGISTER_MATCHER(isAnyPointer); REGISTER_MATCHER(isArrow); REGISTER_MATCHER(isBaseInitializer); REGISTER_MATCHER(isCatchAll); diff --git a/lib/CodeGen/CGStmtOpenMP.cpp b/lib/CodeGen/CGStmtOpenMP.cpp index b378cc6dea..1a9ff6eacd 100644 --- a/lib/CodeGen/CGStmtOpenMP.cpp +++ b/lib/CodeGen/CGStmtOpenMP.cpp @@ -376,14 +376,23 @@ bool CodeGenFunction::EmitOMPFirstprivateClause(const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope) { if (!HaveInsertPoint()) return false; + bool FirstprivateIsLastprivate = false; + llvm::DenseSet Lastprivates; + for (const auto *C : D.getClausesOfKind()) { + for (const auto *D : C->varlists()) + Lastprivates.insert( + cast(cast(D)->getDecl())->getCanonicalDecl()); + } llvm::DenseSet EmittedAsFirstprivate; for (const auto *C : D.getClausesOfKind()) { auto IRef = C->varlist_begin(); auto InitsRef = C->inits().begin(); for (auto IInit : C->private_copies()) { auto *OrigVD = cast(cast(*IRef)->getDecl()); - if (EmittedAsFirstprivate.count(OrigVD) == 0) { - EmittedAsFirstprivate.insert(OrigVD); + FirstprivateIsLastprivate = + FirstprivateIsLastprivate || + (Lastprivates.count(OrigVD->getCanonicalDecl()) > 0); + if (EmittedAsFirstprivate.insert(OrigVD->getCanonicalDecl()).second) { auto *VD = cast(cast(IInit)->getDecl()); auto *VDInit = cast(cast(*InitsRef)->getDecl()); bool IsRegistered; @@ -443,7 +452,7 @@ bool CodeGenFunction::EmitOMPFirstprivateClause(const OMPExecutableDirective &D, ++IRef, ++InitsRef; } } - return !EmittedAsFirstprivate.empty(); + return FirstprivateIsLastprivate && !EmittedAsFirstprivate.empty(); } void CodeGenFunction::EmitOMPPrivateClause( @@ -490,7 +499,6 @@ bool CodeGenFunction::EmitOMPCopyinClause(const OMPExecutableDirective &D) { auto *VD = cast(cast(*IRef)->getDecl()); QualType Type = VD->getType(); if (CopiedVars.insert(VD->getCanonicalDecl()).second) { - // Get the address of the master variable. If we are emitting code with // TLS support, the address is passed from the master as field in the // captured declaration. @@ -964,12 +972,11 @@ void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) { auto &&CodeGen = [&S](CodeGenFunction &CGF) { OMPPrivateScope PrivateScope(CGF); bool Copyins = CGF.EmitOMPCopyinClause(S); - bool Firstprivates = CGF.EmitOMPFirstprivateClause(S, PrivateScope); - if (Copyins || Firstprivates) { + (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope); + if (Copyins) { // Emit implicit barrier to synchronize threads and avoid data races on - // initialization of firstprivate variables or propagation master's thread - // values of threadprivate variables to local instances of that variables - // of all other implicit threads. + // propagation master's thread values of threadprivate variables to local + // instances of that variables of all other implicit threads. CGF.CGM.getOpenMPRuntime().emitBarrierCall( CGF, S.getLocStart(), OMPD_unknown, /*EmitChecks=*/false, /*ForceSimpleCall=*/true); @@ -1605,7 +1612,8 @@ bool CodeGenFunction::EmitOMPWorksharingLoop(const OMPLoopDirective &S) { OMPPrivateScope LoopScope(*this); if (EmitOMPFirstprivateClause(S, LoopScope)) { // Emit implicit barrier to synchronize threads and avoid data races on - // initialization of firstprivate variables. + // initialization of firstprivate variables and post-update of + // lastprivate variables. CGM.getOpenMPRuntime().emitBarrierCall( *this, S.getLocStart(), OMPD_unknown, /*EmitChecks=*/false, /*ForceSimpleCall=*/true); @@ -1804,7 +1812,8 @@ CodeGenFunction::EmitSections(const OMPExecutableDirective &S) { CodeGenFunction::OMPPrivateScope LoopScope(CGF); if (CGF.EmitOMPFirstprivateClause(S, LoopScope)) { // Emit implicit barrier to synchronize threads and avoid data races on - // initialization of firstprivate variables. + // initialization of firstprivate variables and post-update of lastprivate + // variables. CGF.CGM.getOpenMPRuntime().emitBarrierCall( CGF, S.getLocStart(), OMPD_unknown, /*EmitChecks=*/false, /*ForceSimpleCall=*/true); @@ -1883,8 +1892,7 @@ void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &S) { llvm::SmallVector SrcExprs; llvm::SmallVector AssignmentOps; // Check if there are any 'copyprivate' clauses associated with this - // 'single' - // construct. + // 'single' construct. // Build a list of copyprivate variables along with helper expressions // (, , = expressions) for (const auto *C : S.getClausesOfKind()) { @@ -1897,10 +1905,9 @@ void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &S) { } LexicalScope Scope(*this, S.getSourceRange()); // Emit code for 'single' region along with 'copyprivate' clauses - bool HasFirstprivates; - auto &&CodeGen = [&S, &HasFirstprivates](CodeGenFunction &CGF) { + auto &&CodeGen = [&S](CodeGenFunction &CGF) { CodeGenFunction::OMPPrivateScope SingleScope(CGF); - HasFirstprivates = CGF.EmitOMPFirstprivateClause(S, SingleScope); + (void)CGF.EmitOMPFirstprivateClause(S, SingleScope); CGF.EmitOMPPrivateClause(S, SingleScope); (void)SingleScope.Privatize(); @@ -1909,10 +1916,9 @@ void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &S) { CGM.getOpenMPRuntime().emitSingleRegion(*this, CodeGen, S.getLocStart(), CopyprivateVars, DestExprs, SrcExprs, AssignmentOps); - // Emit an implicit barrier at the end (to avoid data race on firstprivate - // init or if no 'nowait' clause was specified and no 'copyprivate' clause). - if ((!S.getSingleClause() || HasFirstprivates) && - CopyprivateVars.empty()) { + // Emit an implicit barrier at the end (to avoid data race if no 'nowait' + // clause was specified and no 'copyprivate' clause). + if (!S.getSingleClause() && CopyprivateVars.empty()) { CGM.getOpenMPRuntime().emitBarrierCall( *this, S.getLocStart(), S.getSingleClause() ? OMPD_unknown : OMPD_single); diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index cb5e7329cd..ae24e4731b 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -3128,6 +3128,22 @@ void FreeBSD::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, } } +void FreeBSD::AddCXXStdlibLibArgs(const ArgList &Args, + ArgStringList &CmdArgs) const { + CXXStdlibType Type = GetCXXStdlibType(Args); + bool Profiling = Args.hasArg(options::OPT_pg); + + switch (Type) { + case ToolChain::CST_Libcxx: + CmdArgs.push_back(Profiling ? "-lc++_p" : "-lc++"); + break; + + case ToolChain::CST_Libstdcxx: + CmdArgs.push_back(Profiling ? "-lstdc++_p" : "-lstdc++"); + break; + } +} + Tool *FreeBSD::buildAssembler() const { return new tools::freebsd::Assembler(*this); } diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h index 127f37f549..11e4c834b4 100644 --- a/lib/Driver/ToolChains.h +++ b/lib/Driver/ToolChains.h @@ -728,6 +728,8 @@ public: void AddClangCXXStdlibIncludeArgs( const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; + void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const override; bool UseSjLjExceptions(const llvm::opt::ArgList &Args) const override; bool isPIEDefault() const override; diff --git a/lib/Index/CMakeLists.txt b/lib/Index/CMakeLists.txt index cb2b931235..8f51ccb11e 100644 --- a/lib/Index/CMakeLists.txt +++ b/lib/Index/CMakeLists.txt @@ -1,16 +1,18 @@ set(LLVM_LINK_COMPONENTS + Core Support ) add_clang_library(clangIndex + CodegenNameGenerator.cpp CommentToXML.cpp - USRGeneration.cpp IndexBody.cpp IndexDecl.cpp IndexingAction.cpp IndexingContext.cpp IndexSymbol.cpp IndexTypeSourceInfo.cpp + USRGeneration.cpp ADDITIONAL_HEADERS IndexingContext.h diff --git a/lib/Index/CodegenNameGenerator.cpp b/lib/Index/CodegenNameGenerator.cpp new file mode 100644 index 0000000000..d663cc36b7 --- /dev/null +++ b/lib/Index/CodegenNameGenerator.cpp @@ -0,0 +1,197 @@ +//===- CodegenNameGenerator.cpp - Codegen name generation -----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Determines the name that the symbol will get for code generation. +// +//===----------------------------------------------------------------------===// + +#include "clang/Index/CodegenNameGenerator.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclObjC.h" +#include "clang/AST/Mangle.h" +#include "clang/AST/VTableBuilder.h" +#include "clang/Basic/TargetInfo.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/Mangler.h" +#include "llvm/Support/raw_ostream.h" + +using namespace clang; +using namespace clang::index; + +struct CodegenNameGenerator::Implementation { + std::unique_ptr MC; + llvm::DataLayout DL; + + Implementation(ASTContext &Ctx) + : MC(Ctx.createMangleContext()), + DL(Ctx.getTargetInfo().getDataLayoutString()) {} + + bool writeName(const Decl *D, raw_ostream &OS) { + // First apply frontend mangling. + SmallString<128> FrontendBuf; + llvm::raw_svector_ostream FrontendBufOS(FrontendBuf); + if (auto *FD = dyn_cast(D)) { + if (FD->isDependentContext()) + return true; + if (writeFuncOrVarName(FD, FrontendBufOS)) + return true; + } else if (auto *VD = dyn_cast(D)) { + if (writeFuncOrVarName(VD, FrontendBufOS)) + return true; + } else if (auto *MD = dyn_cast(D)) { + MC->mangleObjCMethodNameWithoutSize(MD, OS); + return false; + } else if (auto *ID = dyn_cast(D)) { + writeObjCClassName(ID, FrontendBufOS); + } else { + return true; + } + + // Now apply backend mangling. + llvm::Mangler::getNameWithPrefix(OS, FrontendBufOS.str(), DL); + return false; + } + + std::string getName(const Decl *D) { + std::string Name; + { + llvm::raw_string_ostream OS(Name); + writeName(D, OS); + } + return Name; + } + + std::vector getAllManglings(const Decl *D) { + if (!(isa(D) || isa(D))) + return {}; + + const NamedDecl *ND = cast(D); + + ASTContext &Ctx = ND->getASTContext(); + std::unique_ptr M(Ctx.createMangleContext()); + std::unique_ptr DL( + new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString())); + + std::vector Manglings; + + auto hasDefaultCXXMethodCC = [](ASTContext &C, const CXXMethodDecl *MD) { + auto DefaultCC = C.getDefaultCallingConvention(/*IsVariadic=*/false, + /*IsCSSMethod=*/true); + auto CC = MD->getType()->getAs()->getCallConv(); + return CC == DefaultCC; + }; + + if (const auto *CD = dyn_cast_or_null(ND)) { + Manglings.emplace_back(getMangledStructor(CD, Ctor_Base)); + + if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) + if (!CD->getParent()->isAbstract()) + Manglings.emplace_back(getMangledStructor(CD, Ctor_Complete)); + + if (Ctx.getTargetInfo().getCXXABI().isMicrosoft()) + if (CD->hasAttr() && CD->isDefaultConstructor()) + if (!(hasDefaultCXXMethodCC(Ctx, CD) && CD->getNumParams() == 0)) + Manglings.emplace_back(getMangledStructor(CD, Ctor_DefaultClosure)); + } else if (const auto *DD = dyn_cast_or_null(ND)) { + Manglings.emplace_back(getMangledStructor(DD, Dtor_Base)); + if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) { + Manglings.emplace_back(getMangledStructor(DD, Dtor_Complete)); + if (DD->isVirtual()) + Manglings.emplace_back(getMangledStructor(DD, Dtor_Deleting)); + } + } else if (const auto *MD = dyn_cast_or_null(ND)) { + Manglings.emplace_back(getName(ND)); + if (MD->isVirtual()) + if (const auto *TIV = Ctx.getVTableContext()->getThunkInfo(MD)) + for (const auto &T : *TIV) + Manglings.emplace_back(getMangledThunk(MD, T)); + } + + return Manglings; + } + +private: + bool writeFuncOrVarName(const NamedDecl *D, raw_ostream &OS) { + if (MC->shouldMangleDeclName(D)) { + if (const auto *CtorD = dyn_cast(D)) + MC->mangleCXXCtor(CtorD, Ctor_Complete, OS); + else if (const auto *DtorD = dyn_cast(D)) + MC->mangleCXXDtor(DtorD, Dtor_Complete, OS); + else + MC->mangleName(D, OS); + return false; + } else { + IdentifierInfo *II = D->getIdentifier(); + if (!II) + return true; + OS << II->getName(); + return false; + } + } + + void writeObjCClassName(const ObjCInterfaceDecl *D, raw_ostream &OS) { + OS << getClassSymbolPrefix(); + OS << D->getObjCRuntimeNameAsString(); + } + + static StringRef getClassSymbolPrefix() { + return "OBJC_CLASS_$_"; + } + + std::string getMangledStructor(const NamedDecl *ND, unsigned StructorType) { + std::string FrontendBuf; + llvm::raw_string_ostream FOS(FrontendBuf); + + if (const auto *CD = dyn_cast_or_null(ND)) + MC->mangleCXXCtor(CD, static_cast(StructorType), FOS); + else if (const auto *DD = dyn_cast_or_null(ND)) + MC->mangleCXXDtor(DD, static_cast(StructorType), FOS); + + std::string BackendBuf; + llvm::raw_string_ostream BOS(BackendBuf); + + llvm::Mangler::getNameWithPrefix(BOS, FOS.str(), DL); + + return BOS.str(); + } + + std::string getMangledThunk(const CXXMethodDecl *MD, const ThunkInfo &T) { + std::string FrontendBuf; + llvm::raw_string_ostream FOS(FrontendBuf); + + MC->mangleThunk(MD, T, FOS); + + std::string BackendBuf; + llvm::raw_string_ostream BOS(BackendBuf); + + llvm::Mangler::getNameWithPrefix(BOS, FOS.str(), DL); + + return BOS.str(); + } +}; + +CodegenNameGenerator::CodegenNameGenerator(ASTContext &Ctx) + : Impl(new Implementation(Ctx)) { +} + +CodegenNameGenerator::~CodegenNameGenerator() { +} + +bool CodegenNameGenerator::writeName(const Decl *D, raw_ostream &OS) { + return Impl->writeName(D, OS); +} + +std::string CodegenNameGenerator::getName(const Decl *D) { + return Impl->getName(D); +} + +std::vector CodegenNameGenerator::getAllManglings(const Decl *D) { + return Impl->getAllManglings(D); +} diff --git a/lib/Index/IndexSymbol.cpp b/lib/Index/IndexSymbol.cpp index bf3bfd1b95..010ccd42a4 100644 --- a/lib/Index/IndexSymbol.cpp +++ b/lib/Index/IndexSymbol.cpp @@ -11,6 +11,7 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclTemplate.h" +#include "clang/AST/PrettyPrinter.h" using namespace clang; using namespace clang::index; @@ -234,6 +235,24 @@ void index::printSymbolRoles(SymbolRoleSet Roles, raw_ostream &OS) { }); } +bool index::printSymbolName(const Decl *D, const LangOptions &LO, + raw_ostream &OS) { + if (auto *ND = dyn_cast(D)) { + PrintingPolicy Policy(LO); + // Forward references can have different template argument names. Suppress + // the template argument names in constructors to make their name more + // stable. + Policy.SuppressTemplateArgsInCXXConstructors = true; + DeclarationName DeclName = ND->getDeclName(); + if (DeclName.isEmpty()) + return true; + DeclName.print(OS, Policy); + return false; + } else { + return true; + } +} + StringRef index::getSymbolKindString(SymbolKind K) { switch (K) { case SymbolKind::Unknown: return ""; @@ -266,6 +285,7 @@ StringRef index::getSymbolKindString(SymbolKind K) { case SymbolKind::CXXTypeAlias: return "type-alias"; case SymbolKind::CXXInterface: return "c++-__interface"; } + llvm_unreachable("invalid symbol kind"); } StringRef index::getTemplateKindStr(SymbolCXXTemplateKind TK) { @@ -275,6 +295,7 @@ StringRef index::getTemplateKindStr(SymbolCXXTemplateKind TK) { case SymbolCXXTemplateKind::TemplatePartialSpecialization : return "TPS"; case SymbolCXXTemplateKind::TemplateSpecialization: return "TS"; } + llvm_unreachable("invalid template kind"); } StringRef index::getSymbolLanguageString(SymbolLanguage K) { @@ -283,4 +304,5 @@ StringRef index::getSymbolLanguageString(SymbolLanguage K) { case SymbolLanguage::ObjC: return "ObjC"; case SymbolLanguage::CXX: return "C++"; } + llvm_unreachable("invalid symbol language kind"); } diff --git a/lib/Index/IndexingAction.cpp b/lib/Index/IndexingAction.cpp index 46c96a35b6..d744293152 100644 --- a/lib/Index/IndexingAction.cpp +++ b/lib/Index/IndexingAction.cpp @@ -50,6 +50,7 @@ public: protected: void Initialize(ASTContext &Context) override { IndexCtx.setASTContext(Context); + IndexCtx.getDataConsumer().initialize(Context); } bool HandleTopLevelDecl(DeclGroupRef DG) override { @@ -170,5 +171,6 @@ void index::indexASTUnit(ASTUnit &Unit, IndexingOptions Opts) { IndexingContext IndexCtx(Opts, *DataConsumer); IndexCtx.setASTContext(Unit.getASTContext()); + DataConsumer->initialize(Unit.getASTContext()); indexTranslationUnit(Unit, IndexCtx); } diff --git a/lib/Index/IndexingContext.cpp b/lib/Index/IndexingContext.cpp index 91fbbfb268..9ac22f85e1 100644 --- a/lib/Index/IndexingContext.cpp +++ b/lib/Index/IndexingContext.cpp @@ -135,6 +135,7 @@ bool IndexingContext::isTemplateImplicitInstantiation(const Decl *D) { case TSK_ExplicitInstantiationDefinition: return true; } + llvm_unreachable("invalid TemplateSpecializationKind"); } bool IndexingContext::shouldIgnoreIfImplicit(const Decl *D) { diff --git a/lib/Index/USRGeneration.cpp b/lib/Index/USRGeneration.cpp index 3b2954f977..c15838c76c 100644 --- a/lib/Index/USRGeneration.cpp +++ b/lib/Index/USRGeneration.cpp @@ -210,7 +210,12 @@ void USRGenerator::VisitFunctionDecl(const FunctionDecl *D) { VisitTemplateParameterList(FunTmpl->getTemplateParameters()); } else Out << "@F@"; - D->printName(Out); + + PrintingPolicy Policy(Context->getLangOpts()); + // Forward references can have different template argument names. Suppress the + // template argument names in constructors to make their USR more stable. + Policy.SuppressTemplateArgsInCXXConstructors = true; + D->getDeclName().print(Out, Policy); ASTContext &Ctx = *Context; if (!Ctx.getLangOpts().CPlusPlus || D->isExternC()) diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 7192eb5014..db29e72005 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -5818,10 +5818,12 @@ void Sema::CheckStrncatArguments(const CallExpr *CE, //===--- CHECK: Return Address of Stack Variable --------------------------===// -static Expr *EvalVal(Expr *E, SmallVectorImpl &refVars, - Decl *ParentDecl); -static Expr *EvalAddr(Expr* E, SmallVectorImpl &refVars, - Decl *ParentDecl); +static const Expr *EvalVal(const Expr *E, + SmallVectorImpl &refVars, + const Decl *ParentDecl); +static const Expr *EvalAddr(const Expr *E, + SmallVectorImpl &refVars, + const Decl *ParentDecl); /// CheckReturnStackAddr - Check if a return statement returns the address /// of a stack variable. @@ -5829,8 +5831,8 @@ static void CheckReturnStackAddr(Sema &S, Expr *RetValExp, QualType lhsType, SourceLocation ReturnLoc) { - Expr *stackE = nullptr; - SmallVector refVars; + const Expr *stackE = nullptr; + SmallVector refVars; // Perform checking for returned stack addresses, local blocks, // label addresses or references to temporaries. @@ -5858,7 +5860,8 @@ CheckReturnStackAddr(Sema &S, Expr *RetValExp, QualType lhsType, diagRange = refVars[0]->getSourceRange(); } - if (DeclRefExpr *DR = dyn_cast(stackE)) { //address of local var. + if (const DeclRefExpr *DR = dyn_cast(stackE)) { + // address of local var S.Diag(diagLoc, diag::warn_ret_stack_addr_ref) << lhsType->isReferenceType() << DR->getDecl()->getDeclName() << diagRange; } else if (isa(stackE)) { // local block. @@ -5873,12 +5876,12 @@ CheckReturnStackAddr(Sema &S, Expr *RetValExp, QualType lhsType, // Display the "trail" of reference variables that we followed until we // found the problematic expression using notes. for (unsigned i = 0, e = refVars.size(); i != e; ++i) { - VarDecl *VD = cast(refVars[i]->getDecl()); + const VarDecl *VD = cast(refVars[i]->getDecl()); // If this var binds to another reference var, show the range of the next // var, otherwise the var binds to the problematic expression, in which case // show the range of the expression. - SourceRange range = (i < e-1) ? refVars[i+1]->getSourceRange() - : stackE->getSourceRange(); + SourceRange range = (i < e - 1) ? refVars[i + 1]->getSourceRange() + : stackE->getSourceRange(); S.Diag(VD->getLocation(), diag::note_ref_var_local_bind) << VD->getDeclName() << range; } @@ -5910,8 +5913,9 @@ CheckReturnStackAddr(Sema &S, Expr *RetValExp, QualType lhsType, /// * arbitrary interplay between "&" and "*" operators /// * pointer arithmetic from an address of a stack variable /// * taking the address of an array element where the array is on the stack -static Expr *EvalAddr(Expr *E, SmallVectorImpl &refVars, - Decl *ParentDecl) { +static const Expr *EvalAddr(const Expr *E, + SmallVectorImpl &refVars, + const Decl *ParentDecl) { if (E->isTypeDependent()) return nullptr; @@ -5928,13 +5932,13 @@ static Expr *EvalAddr(Expr *E, SmallVectorImpl &refVars, // EvalAddr and EvalVal appropriately. switch (E->getStmtClass()) { case Stmt::DeclRefExprClass: { - DeclRefExpr *DR = cast(E); + const DeclRefExpr *DR = cast(E); // If we leave the immediate function, the lifetime isn't about to end. if (DR->refersToEnclosingVariableOrCapture()) return nullptr; - if (VarDecl *V = dyn_cast(DR->getDecl())) + if (const VarDecl *V = dyn_cast(DR->getDecl())) // If this is a reference variable, follow through to the expression that // it points to. if (V->hasLocalStorage() && @@ -5950,44 +5954,44 @@ static Expr *EvalAddr(Expr *E, SmallVectorImpl &refVars, case Stmt::UnaryOperatorClass: { // The only unary operator that make sense to handle here // is AddrOf. All others don't make sense as pointers. - UnaryOperator *U = cast(E); + const UnaryOperator *U = cast(E); if (U->getOpcode() == UO_AddrOf) return EvalVal(U->getSubExpr(), refVars, ParentDecl); - else - return nullptr; + return nullptr; } case Stmt::BinaryOperatorClass: { // Handle pointer arithmetic. All other binary operators are not valid // in this context. - BinaryOperator *B = cast(E); + const BinaryOperator *B = cast(E); BinaryOperatorKind op = B->getOpcode(); if (op != BO_Add && op != BO_Sub) return nullptr; - Expr *Base = B->getLHS(); + const Expr *Base = B->getLHS(); // Determine which argument is the real pointer base. It could be // the RHS argument instead of the LHS. - if (!Base->getType()->isPointerType()) Base = B->getRHS(); + if (!Base->getType()->isPointerType()) + Base = B->getRHS(); - assert (Base->getType()->isPointerType()); + assert(Base->getType()->isPointerType()); return EvalAddr(Base, refVars, ParentDecl); } // For conditional operators we need to see if either the LHS or RHS are // valid DeclRefExpr*s. If one of them is valid, we return it. case Stmt::ConditionalOperatorClass: { - ConditionalOperator *C = cast(E); + const ConditionalOperator *C = cast(E); // Handle the GNU extension for missing LHS. // FIXME: That isn't a ConditionalOperator, so doesn't get here. - if (Expr *LHSExpr = C->getLHS()) { + if (const Expr *LHSExpr = C->getLHS()) { // In C++, we can have a throw-expression, which has 'void' type. if (!LHSExpr->getType()->isVoidType()) - if (Expr *LHS = EvalAddr(LHSExpr, refVars, ParentDecl)) + if (const Expr *LHS = EvalAddr(LHSExpr, refVars, ParentDecl)) return LHS; } @@ -6020,7 +6024,7 @@ static Expr *EvalAddr(Expr *E, SmallVectorImpl &refVars, case Stmt::CXXDynamicCastExprClass: case Stmt::CXXConstCastExprClass: case Stmt::CXXReinterpretCastExprClass: { - Expr* SubExpr = cast(E)->getSubExpr(); + const Expr* SubExpr = cast(E)->getSubExpr(); switch (cast(E)->getCastKind()) { case CK_LValueToRValue: case CK_NoOp: @@ -6050,13 +6054,12 @@ static Expr *EvalAddr(Expr *E, SmallVectorImpl &refVars, } case Stmt::MaterializeTemporaryExprClass: - if (Expr *Result = EvalAddr( - cast(E)->GetTemporaryExpr(), - refVars, ParentDecl)) + if (const Expr *Result = + EvalAddr(cast(E)->GetTemporaryExpr(), + refVars, ParentDecl)) return Result; - return E; - + // Everything else: we simply don't reason about them. default: return nullptr; @@ -6065,141 +6068,147 @@ static Expr *EvalAddr(Expr *E, SmallVectorImpl &refVars, /// EvalVal - This function is complements EvalAddr in the mutual recursion. /// See the comments for EvalAddr for more details. -static Expr *EvalVal(Expr *E, SmallVectorImpl &refVars, - Decl *ParentDecl) { -do { - // We should only be called for evaluating non-pointer expressions, or - // expressions with a pointer type that are not used as references but instead - // are l-values (e.g., DeclRefExpr with a pointer type). +static const Expr *EvalVal(const Expr *E, + SmallVectorImpl &refVars, + const Decl *ParentDecl) { + do { + // We should only be called for evaluating non-pointer expressions, or + // expressions with a pointer type that are not used as references but + // instead + // are l-values (e.g., DeclRefExpr with a pointer type). - // Our "symbolic interpreter" is just a dispatch off the currently - // viewed AST node. We then recursively traverse the AST by calling - // EvalAddr and EvalVal appropriately. + // Our "symbolic interpreter" is just a dispatch off the currently + // viewed AST node. We then recursively traverse the AST by calling + // EvalAddr and EvalVal appropriately. - E = E->IgnoreParens(); - switch (E->getStmtClass()) { - case Stmt::ImplicitCastExprClass: { - ImplicitCastExpr *IE = cast(E); - if (IE->getValueKind() == VK_LValue) { - E = IE->getSubExpr(); - continue; - } - return nullptr; - } - - case Stmt::ExprWithCleanupsClass: - return EvalVal(cast(E)->getSubExpr(), refVars,ParentDecl); - - case Stmt::DeclRefExprClass: { - // When we hit a DeclRefExpr we are looking at code that refers to a - // variable's name. If it's not a reference variable we check if it has - // local storage within the function, and if so, return the expression. - DeclRefExpr *DR = cast(E); - - // If we leave the immediate function, the lifetime isn't about to end. - if (DR->refersToEnclosingVariableOrCapture()) + E = E->IgnoreParens(); + switch (E->getStmtClass()) { + case Stmt::ImplicitCastExprClass: { + const ImplicitCastExpr *IE = cast(E); + if (IE->getValueKind() == VK_LValue) { + E = IE->getSubExpr(); + continue; + } return nullptr; + } - if (VarDecl *V = dyn_cast(DR->getDecl())) { - // Check if it refers to itself, e.g. "int& i = i;". - if (V == ParentDecl) - return DR; + case Stmt::ExprWithCleanupsClass: + return EvalVal(cast(E)->getSubExpr(), refVars, + ParentDecl); - if (V->hasLocalStorage()) { - if (!V->getType()->isReferenceType()) + case Stmt::DeclRefExprClass: { + // When we hit a DeclRefExpr we are looking at code that refers to a + // variable's name. If it's not a reference variable we check if it has + // local storage within the function, and if so, return the expression. + const DeclRefExpr *DR = cast(E); + + // If we leave the immediate function, the lifetime isn't about to end. + if (DR->refersToEnclosingVariableOrCapture()) + return nullptr; + + if (const VarDecl *V = dyn_cast(DR->getDecl())) { + // Check if it refers to itself, e.g. "int& i = i;". + if (V == ParentDecl) return DR; - // Reference variable, follow through to the expression that - // it points to. - if (V->hasInit()) { - // Add the reference variable to the "trail". - refVars.push_back(DR); - return EvalVal(V->getInit(), refVars, V); + if (V->hasLocalStorage()) { + if (!V->getType()->isReferenceType()) + return DR; + + // Reference variable, follow through to the expression that + // it points to. + if (V->hasInit()) { + // Add the reference variable to the "trail". + refVars.push_back(DR); + return EvalVal(V->getInit(), refVars, V); + } } } + + return nullptr; } - return nullptr; - } + case Stmt::UnaryOperatorClass: { + // The only unary operator that make sense to handle here + // is Deref. All others don't resolve to a "name." This includes + // handling all sorts of rvalues passed to a unary operator. + const UnaryOperator *U = cast(E); - case Stmt::UnaryOperatorClass: { - // The only unary operator that make sense to handle here - // is Deref. All others don't resolve to a "name." This includes - // handling all sorts of rvalues passed to a unary operator. - UnaryOperator *U = cast(E); + if (U->getOpcode() == UO_Deref) + return EvalAddr(U->getSubExpr(), refVars, ParentDecl); - if (U->getOpcode() == UO_Deref) - return EvalAddr(U->getSubExpr(), refVars, ParentDecl); + return nullptr; + } - return nullptr; - } + case Stmt::ArraySubscriptExprClass: { + // Array subscripts are potential references to data on the stack. We + // retrieve the DeclRefExpr* for the array variable if it indeed + // has local storage. + const auto *ASE = cast(E); + if (ASE->isTypeDependent()) + return nullptr; + return EvalAddr(ASE->getBase(), refVars, ParentDecl); + } - case Stmt::ArraySubscriptExprClass: { - // Array subscripts are potential references to data on the stack. We - // retrieve the DeclRefExpr* for the array variable if it indeed - // has local storage. - return EvalAddr(cast(E)->getBase(), refVars,ParentDecl); - } + case Stmt::OMPArraySectionExprClass: { + return EvalAddr(cast(E)->getBase(), refVars, + ParentDecl); + } - case Stmt::OMPArraySectionExprClass: { - return EvalAddr(cast(E)->getBase(), refVars, - ParentDecl); - } + case Stmt::ConditionalOperatorClass: { + // For conditional operators we need to see if either the LHS or RHS are + // non-NULL Expr's. If one is non-NULL, we return it. + const ConditionalOperator *C = cast(E); - case Stmt::ConditionalOperatorClass: { - // For conditional operators we need to see if either the LHS or RHS are - // non-NULL Expr's. If one is non-NULL, we return it. - ConditionalOperator *C = cast(E); + // Handle the GNU extension for missing LHS. + if (const Expr *LHSExpr = C->getLHS()) { + // In C++, we can have a throw-expression, which has 'void' type. + if (!LHSExpr->getType()->isVoidType()) + if (const Expr *LHS = EvalVal(LHSExpr, refVars, ParentDecl)) + return LHS; + } - // Handle the GNU extension for missing LHS. - if (Expr *LHSExpr = C->getLHS()) { // In C++, we can have a throw-expression, which has 'void' type. - if (!LHSExpr->getType()->isVoidType()) - if (Expr *LHS = EvalVal(LHSExpr, refVars, ParentDecl)) - return LHS; + if (C->getRHS()->getType()->isVoidType()) + return nullptr; + + return EvalVal(C->getRHS(), refVars, ParentDecl); } - // In C++, we can have a throw-expression, which has 'void' type. - if (C->getRHS()->getType()->isVoidType()) - return nullptr; + // Accesses to members are potential references to data on the stack. + case Stmt::MemberExprClass: { + const MemberExpr *M = cast(E); - return EvalVal(C->getRHS(), refVars, ParentDecl); - } + // Check for indirect access. We only want direct field accesses. + if (M->isArrow()) + return nullptr; - // Accesses to members are potential references to data on the stack. - case Stmt::MemberExprClass: { - MemberExpr *M = cast(E); + // Check whether the member type is itself a reference, in which case + // we're not going to refer to the member, but to what the member refers + // to. + if (M->getMemberDecl()->getType()->isReferenceType()) + return nullptr; - // Check for indirect access. We only want direct field accesses. - if (M->isArrow()) - return nullptr; + return EvalVal(M->getBase(), refVars, ParentDecl); + } - // Check whether the member type is itself a reference, in which case - // we're not going to refer to the member, but to what the member refers to. - if (M->getMemberDecl()->getType()->isReferenceType()) - return nullptr; - - return EvalVal(M->getBase(), refVars, ParentDecl); - } - - case Stmt::MaterializeTemporaryExprClass: - if (Expr *Result = EvalVal( - cast(E)->GetTemporaryExpr(), - refVars, ParentDecl)) - return Result; - - return E; - - default: - // Check that we don't return or take the address of a reference to a - // temporary. This is only useful in C++. - if (!E->isTypeDependent() && E->isRValue()) + case Stmt::MaterializeTemporaryExprClass: + if (const Expr *Result = + EvalVal(cast(E)->GetTemporaryExpr(), + refVars, ParentDecl)) + return Result; return E; - // Everything else: we simply don't reason about them. - return nullptr; - } -} while (true); + default: + // Check that we don't return or take the address of a reference to a + // temporary. This is only useful in C++. + if (!E->isTypeDependent() && E->isRValue()) + return E; + + // Everything else: we simply don't reason about them. + return nullptr; + } + } while (true); } void diff --git a/test/Driver/freebsd.cpp b/test/Driver/freebsd.cpp index dea3267233..175b873bf4 100644 --- a/test/Driver/freebsd.cpp +++ b/test/Driver/freebsd.cpp @@ -2,5 +2,12 @@ // RUN: | FileCheck --check-prefix=CHECK-TEN %s // RUN: %clangxx %s -### -o %t.o -target amd64-unknown-freebsd9.2 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-NINE %s -// CHECK-TEN: -lc++ -// CHECK-NINE: -lstdc++ +// CHECK-TEN: "-lc++" "-lm" +// CHECK-NINE: "-lstdc++" "-lm" + +// RUN: %clangxx %s -### -pg -o %t.o -target amd64-unknown-freebsd10.0 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-PG-TEN %s +// RUN: %clangxx %s -### -pg -o %t.o -target amd64-unknown-freebsd9.2 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-PG-NINE %s +// CHECK-PG-TEN: "-lc++_p" "-lm_p" +// CHECK-PG-NINE: "-lstdc++_p" "-lm_p" diff --git a/test/Index/Core/index-source.cpp b/test/Index/Core/index-source.cpp new file mode 100644 index 0000000000..7544646826 --- /dev/null +++ b/test/Index/Core/index-source.cpp @@ -0,0 +1,9 @@ +// RUN: c-index-test core -print-source-symbols -- %s -target x86_64-apple-macosx10.7 | FileCheck %s + +template +class TemplCls { +// CHECK: [[@LINE-1]]:7 | c++-class/C++ | TemplCls | c:@ST>1#T@TemplCls | | Def | rel: 0 + TemplCls(int x); + // CHECK: [[@LINE-1]]:3 | constructor/C++ | TemplCls | c:@ST>1#T@TemplCls@F@TemplCls#I# | | Decl/RelChild | rel: 1 + // CHECK-NEXT: RelChild | TemplCls | c:@ST>1#T@TemplCls +}; diff --git a/test/Index/Core/index-source.m b/test/Index/Core/index-source.m index 42c23505b1..0fdae7ae5f 100644 --- a/test/Index/Core/index-source.m +++ b/test/Index/Core/index-source.m @@ -1,8 +1,8 @@ -// RUN: c-index-test core -print-source-symbols -- %s | FileCheck %s +// RUN: c-index-test core -print-source-symbols -- %s -target x86_64-apple-macosx10.7 | FileCheck %s @interface Base -// CHECK: [[@LINE-1]]:12 | objc-class/ObjC | Base | c:objc(cs)Base | Decl | rel: 0 +// CHECK: [[@LINE-1]]:12 | objc-class/ObjC | Base | c:objc(cs)Base | _OBJC_CLASS_$_Base | Decl | rel: 0 -(void)meth; -// CHECK: [[@LINE-1]]:1 | objc-instance-method/ObjC | meth | c:objc(cs)Base(im)meth | Decl/Dyn/RelChild | rel: 1 +// CHECK: [[@LINE-1]]:1 | objc-instance-method/ObjC | meth | c:objc(cs)Base(im)meth | -[Base meth] | Decl/Dyn/RelChild | rel: 1 // CHECK-NEXT: RelChild | Base | c:objc(cs)Base @end diff --git a/test/OpenMP/for_firstprivate_codegen.cpp b/test/OpenMP/for_firstprivate_codegen.cpp index 01a9355945..5b1a406941 100644 --- a/test/OpenMP/for_firstprivate_codegen.cpp +++ b/test/OpenMP/for_firstprivate_codegen.cpp @@ -95,7 +95,7 @@ int main() { // LAMBDA: [[SIVAR2_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR2_PRIVATE_ADDR_REF]] // LAMBDA: store i{{[0-9]+}} [[SIVAR2_VAL]], i{{[0-9]+}}* [[SIVAR2_PRIVATE_ADDR]] - // LAMBDA: call void @__kmpc_barrier( + // LAMBDA-NOT: call void @__kmpc_barrier( g = 1; g1 = 1; sivar = 2; @@ -158,7 +158,7 @@ int main() { // BLOCKS: [[SIVAR2_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_REF_ADDRR]] // BLOCKS: store i{{[0-9]+}} {{.+}}, i{{[0-9]+}}* [[SIVAR2_PRIVATE_ADDR]] - // BLOCKS: call void @__kmpc_barrier( + // BLOCKS-NOT: call void @__kmpc_barrier( g = 1; g1 =1; sivar = 2; @@ -246,7 +246,7 @@ int main() { // CHECK: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIV]] // Synchronization for initialization. -// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) +// CHECK-NOT: call void @__kmpc_barrier( // CHECK: call void @__kmpc_for_static_init_4( // CHECK: call void @__kmpc_for_static_fini( @@ -310,10 +310,8 @@ int main() { // CHECK: call {{.*}} [[S_INT_TY_COPY_CONSTR]]([[S_INT_TY]]* [[VAR_PRIV]], [[S_INT_TY]]* {{.*}} [[VAR_REF]], [[ST_TY]]* [[ST_TY_TEMP]]) // CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]]) -// Synchronization for initialization. -// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]] -// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] -// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) +// No synchronization for initialization. +// CHECK-NOT: call void @__kmpc_barrier( // CHECK: call void @__kmpc_for_static_init_4( // CHECK: call void @__kmpc_for_static_fini( diff --git a/test/OpenMP/parallel_firstprivate_codegen.cpp b/test/OpenMP/parallel_firstprivate_codegen.cpp index d0da8cea87..cd50a0cb0e 100644 --- a/test/OpenMP/parallel_firstprivate_codegen.cpp +++ b/test/OpenMP/parallel_firstprivate_codegen.cpp @@ -31,7 +31,6 @@ struct S { // CHECK-DAG: [[S_FLOAT_TY:%.+]] = type { float } // CHECK-DAG: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} } // CHECK-DAG: [[ST_TY:%.+]] = type { i{{[0-9]+}}, i{{[0-9]+}} } -// CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8* template T tmain() { @@ -70,7 +69,7 @@ int main() { // LAMBDA: store i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]], align 128 // LAMBDA: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_REF]] // LAMBDA: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]] - // LAMBDA: call {{.*}}void @__kmpc_barrier( + // LAMBDA-NOT: call {{.*}}void @__kmpc_barrier( g = 1; sivar = 2; // LAMBDA: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], @@ -115,7 +114,7 @@ int main() { // BLOCK: [[SIVAR_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[SIVAR_REF_ADDR]] // BLOCKS: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR_REF]], // BLOCKS: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIVATE_ADDR]], - // BLOCKS: call {{.*}}void @__kmpc_barrier( + // BLOCKS-NOT: call {{.*}}void @__kmpc_barrier( g = 1; sivar = 2; // BLOCKS: store i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]], @@ -244,9 +243,7 @@ int main() { // CHECK: call {{.*}} [[ST_TY_DEFAULT_CONSTR]]([[ST_TY]]* [[ST_TY_TEMP:%.+]]) // CHECK: call {{.*}} [[S_INT_TY_COPY_CONSTR]]([[S_INT_TY]]* [[VAR_PRIV]], [[S_INT_TY]]* {{.*}} [[VAR_REF]], [[ST_TY]]* [[ST_TY_TEMP]]) // CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]]) -// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]] -// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] -// CHECK: call {{.*}}void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) +// CHECK-NOT: call {{.*}}void @__kmpc_barrier( // CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[VAR_PRIV]]) // CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* // CHECK: ret void diff --git a/test/OpenMP/sections_firstprivate_codegen.cpp b/test/OpenMP/sections_firstprivate_codegen.cpp index 0e9273f52c..dd854b57b1 100644 --- a/test/OpenMP/sections_firstprivate_codegen.cpp +++ b/test/OpenMP/sections_firstprivate_codegen.cpp @@ -59,7 +59,6 @@ S s_arr[] = {1, 2}; // CHECK-DAG: [[VAR:@.+]] = global [[S_FLOAT_TY]] zeroinitializer, S var(3); // CHECK-DAG: [[SIVAR:@.+]] = internal global i{{[0-9]+}} 0, -// CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8* // CHECK-DAG: [[SECTIONS_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 194, i32 0, i32 0, i8* // CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]]) @@ -94,7 +93,7 @@ int main() { // LAMBDA: [[SIVAR1_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR1_REF]] // LAMBDA: store i{{[0-9]+}} [[SIVAR1_VAL]], i{{[0-9]+}}* [[SIVAR1_PRIVATE_ADDR]] - // LAMBDA: call void @__kmpc_barrier( + // LAMBDA-NOT: call void @__kmpc_barrier( { g = 1; sivar = 10; @@ -154,7 +153,7 @@ int main() { // BLOCKS: [[SIVAR1_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR1_REF]], // BLOCKS: store i{{[0-9]+}} [[SIVAR1_VAL]], i{{[0-9]+}}* [[SIVAR1_PRIVATE_ADDR]], - // BLOCKS: call void @__kmpc_barrier( + // BLOCKS-NOT: call void @__kmpc_barrier( { g = 1; sivar = 10; @@ -242,7 +241,7 @@ int main() { // CHECK: [[SIVAR_VAL:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIVAR]], // CHECK: store i{{[0-9]+}} [[SIVAR_VAL]], i{{[0-9]+}}* [[SIVAR_PRIV]], -// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) +// CHECK-NOT: call void @__kmpc_barrier( // CHECK: call void @__kmpc_for_static_init_4( // CHECK: call void @__kmpc_for_static_fini( @@ -304,10 +303,8 @@ int main() { // CHECK: call {{.*}} [[S_INT_TY_COPY_CONSTR]]([[S_INT_TY]]* [[VAR_PRIV]], [[S_INT_TY]]* {{.*}} [[VAR_REF]], [[ST_TY]]* [[ST_TY_TEMP]]) // CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]]) -// Synchronization for initialization. -// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]] -// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] -// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) +// No synchronization for initialization. +// CHECK-NOT: call void @__kmpc_barrier( // CHECK: call void @__kmpc_for_static_init_4( // CHECK: call void @__kmpc_for_static_fini( diff --git a/test/OpenMP/single_firstprivate_codegen.cpp b/test/OpenMP/single_firstprivate_codegen.cpp index cc72addb5f..8407f77243 100644 --- a/test/OpenMP/single_firstprivate_codegen.cpp +++ b/test/OpenMP/single_firstprivate_codegen.cpp @@ -57,7 +57,6 @@ int vec[] = {1, 2}; S s_arr[] = {1, 2}; // CHECK-DAG: [[VAR:@.+]] = global [[S_FLOAT_TY]] zeroinitializer, S var(3); -// CHECK-DAG: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8* // CHECK-DAG: [[SINGLE_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 322, i32 0, i32 0, i8* // CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]]) @@ -215,7 +214,7 @@ int main() { // CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* // CHECK: call void @__kmpc_end_single( -// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]]) +// CHECK-NOT: call void @__kmpc_barrier( // CHECK: = call {{.*}}i{{.+}} [[TMAIN_INT:@.+]]() diff --git a/test/SemaCXX/return-stack-addr-2.cpp b/test/SemaCXX/return-stack-addr-2.cpp new file mode 100644 index 0000000000..ad27567fcd --- /dev/null +++ b/test/SemaCXX/return-stack-addr-2.cpp @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -std=c++11 %s +// expected-no-diagnostics + +namespace PR26599 { +template +struct S; + +struct I {}; + +template +void *&non_pointer() { + void *&r = S()[I{}]; + return r; +} + +template +void *&pointer() { + void *&r = S()[nullptr]; + return r; +} +} + diff --git a/tools/c-index-test/CMakeLists.txt b/tools/c-index-test/CMakeLists.txt index 1228a65486..3958e95a90 100644 --- a/tools/c-index-test/CMakeLists.txt +++ b/tools/c-index-test/CMakeLists.txt @@ -22,6 +22,9 @@ if (LLVM_BUILD_STATIC) else() target_link_libraries(c-index-test libclang + clangAST + clangBasic + clangFrontend clangIndex ) endif() diff --git a/tools/c-index-test/core_main.cpp b/tools/c-index-test/core_main.cpp index ce37b56256..e72b9f93ef 100644 --- a/tools/c-index-test/core_main.cpp +++ b/tools/c-index-test/core_main.cpp @@ -14,6 +14,7 @@ #include "clang/Index/IndexingAction.h" #include "clang/Index/IndexDataConsumer.h" #include "clang/Index/USRGeneration.h" +#include "clang/Index/CodegenNameGenerator.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Signals.h" #include "llvm/Support/raw_ostream.h" @@ -60,11 +61,16 @@ namespace { class PrintIndexDataConsumer : public IndexDataConsumer { raw_ostream &OS; + std::unique_ptr CGNameGen; public: PrintIndexDataConsumer(raw_ostream &OS) : OS(OS) { } + void initialize(ASTContext &Ctx) override { + CGNameGen.reset(new CodegenNameGenerator(Ctx)); + } + bool handleDeclOccurence(const Decl *D, SymbolRoleSet Roles, ArrayRef Relations, FileID FID, unsigned Offset, @@ -82,6 +88,10 @@ public: printSymbolNameAndUSR(D, Ctx, OS); OS << " | "; + if (CGNameGen->writeName(D, OS)) + OS << ""; + OS << " | "; + printSymbolRoles(Roles, OS); OS << " | "; @@ -123,9 +133,8 @@ static bool printSourceSymbols(ArrayRef Args) { /*WrappedAction=*/nullptr); auto PCHContainerOps = std::make_shared(); - ASTUnit *Unit = - ASTUnit::LoadFromCompilerInvocationAction(CInvok.get(), PCHContainerOps, - Diags, IndexAction.get()); + std::unique_ptr Unit(ASTUnit::LoadFromCompilerInvocationAction( + CInvok.get(), PCHContainerOps, Diags, IndexAction.get())); if (!Unit) return true; @@ -147,10 +156,7 @@ static void printSymbolInfo(SymbolInfo SymInfo, raw_ostream &OS) { static void printSymbolNameAndUSR(const Decl *D, ASTContext &Ctx, raw_ostream &OS) { - if (auto *ND = dyn_cast(D)) { - PrintingPolicy PrintPolicy(Ctx.getLangOpts()); - ND->getDeclName().print(OS, PrintPolicy); - } else { + if (printSymbolName(D, Ctx.getLangOpts(), OS)) { OS << ""; } OS << " | "; diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index 6f2800514a..1526900dc4 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -22,17 +22,15 @@ #include "CXType.h" #include "CursorVisitor.h" #include "clang/AST/Attr.h" -#include "clang/AST/Mangle.h" #include "clang/AST/StmtVisitor.h" -#include "clang/AST/VTableBuilder.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticCategories.h" #include "clang/Basic/DiagnosticIDs.h" -#include "clang/Basic/TargetInfo.h" #include "clang/Basic/Version.h" #include "clang/Frontend/ASTUnit.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendDiagnostic.h" +#include "clang/Index/CodegenNameGenerator.h" #include "clang/Index/CommentToXML.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/Lexer.h" @@ -43,8 +41,6 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Config/llvm-config.h" -#include "llvm/IR/DataLayout.h" -#include "llvm/IR/Mangler.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/CrashRecoveryContext.h" #include "llvm/Support/Format.h" @@ -3976,59 +3972,6 @@ static SourceLocation getLocationFromExpr(const Expr *E) { return E->getLocStart(); } -static std::string getMangledStructor(std::unique_ptr &M, - std::unique_ptr &DL, - const NamedDecl *ND, - unsigned StructorType) { - std::string FrontendBuf; - llvm::raw_string_ostream FOS(FrontendBuf); - - if (const auto *CD = dyn_cast_or_null(ND)) - M->mangleCXXCtor(CD, static_cast(StructorType), FOS); - else if (const auto *DD = dyn_cast_or_null(ND)) - M->mangleCXXDtor(DD, static_cast(StructorType), FOS); - - std::string BackendBuf; - llvm::raw_string_ostream BOS(BackendBuf); - - llvm::Mangler::getNameWithPrefix(BOS, llvm::Twine(FOS.str()), *DL); - - return BOS.str(); -} - -static std::string getMangledName(std::unique_ptr &M, - std::unique_ptr &DL, - const NamedDecl *ND) { - std::string FrontendBuf; - llvm::raw_string_ostream FOS(FrontendBuf); - - M->mangleName(ND, FOS); - - std::string BackendBuf; - llvm::raw_string_ostream BOS(BackendBuf); - - llvm::Mangler::getNameWithPrefix(BOS, llvm::Twine(FOS.str()), *DL); - - return BOS.str(); -} - -static std::string getMangledThunk(std::unique_ptr &M, - std::unique_ptr &DL, - const CXXMethodDecl *MD, - const ThunkInfo &T) { - std::string FrontendBuf; - llvm::raw_string_ostream FOS(FrontendBuf); - - M->mangleThunk(MD, T, FOS); - - std::string BackendBuf; - llvm::raw_string_ostream BOS(BackendBuf); - - llvm::Mangler::getNameWithPrefix(BOS, llvm::Twine(FOS.str()), *DL); - - return BOS.str(); -} - extern "C" { unsigned clang_visitChildren(CXCursor parent, @@ -4377,29 +4320,9 @@ CXString clang_Cursor_getMangling(CXCursor C) { if (!D || !(isa(D) || isa(D))) return cxstring::createEmpty(); - // First apply frontend mangling. - const NamedDecl *ND = cast(D); - ASTContext &Ctx = ND->getASTContext(); - std::unique_ptr MC(Ctx.createMangleContext()); - - std::string FrontendBuf; - llvm::raw_string_ostream FrontendBufOS(FrontendBuf); - if (MC->shouldMangleDeclName(ND)) { - MC->mangleName(ND, FrontendBufOS); - } else { - ND->printName(FrontendBufOS); - } - - // Now apply backend mangling. - std::unique_ptr DL( - new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString())); - - std::string FinalBuf; - llvm::raw_string_ostream FinalBufOS(FinalBuf); - llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()), - *DL); - - return cxstring::createDup(FinalBufOS.str()); + ASTContext &Ctx = D->getASTContext(); + index::CodegenNameGenerator CGNameGen(Ctx); + return cxstring::createDup(CGNameGen.getName(D)); } CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) { @@ -4410,49 +4333,9 @@ CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) { if (!(isa(D) || isa(D))) return nullptr; - const NamedDecl *ND = cast(D); - - ASTContext &Ctx = ND->getASTContext(); - std::unique_ptr M(Ctx.createMangleContext()); - std::unique_ptr DL( - new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString())); - - std::vector Manglings; - - auto hasDefaultCXXMethodCC = [](ASTContext &C, const CXXMethodDecl *MD) { - auto DefaultCC = C.getDefaultCallingConvention(/*IsVariadic=*/false, - /*IsCSSMethod=*/true); - auto CC = MD->getType()->getAs()->getCallConv(); - return CC == DefaultCC; - }; - - if (const auto *CD = dyn_cast_or_null(ND)) { - Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Base)); - - if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) - if (!CD->getParent()->isAbstract()) - Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Complete)); - - if (Ctx.getTargetInfo().getCXXABI().isMicrosoft()) - if (CD->hasAttr() && CD->isDefaultConstructor()) - if (!(hasDefaultCXXMethodCC(Ctx, CD) && CD->getNumParams() == 0)) - Manglings.emplace_back(getMangledStructor(M, DL, CD, - Ctor_DefaultClosure)); - } else if (const auto *DD = dyn_cast_or_null(ND)) { - Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Base)); - if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) { - Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Complete)); - if (DD->isVirtual()) - Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Deleting)); - } - } else if (const auto *MD = dyn_cast_or_null(ND)) { - Manglings.emplace_back(getMangledName(M, DL, ND)); - if (MD->isVirtual()) - if (const auto *TIV = Ctx.getVTableContext()->getThunkInfo(MD)) - for (const auto &T : *TIV) - Manglings.emplace_back(getMangledThunk(M, DL, MD, T)); - } - + ASTContext &Ctx = D->getASTContext(); + index::CodegenNameGenerator CGNameGen(Ctx); + std::vector Manglings = CGNameGen.getAllManglings(D); return cxstring::createSet(Manglings); } diff --git a/tools/libclang/CXIndexDataConsumer.cpp b/tools/libclang/CXIndexDataConsumer.cpp index f6f8e30679..322725ec65 100644 --- a/tools/libclang/CXIndexDataConsumer.cpp +++ b/tools/libclang/CXIndexDataConsumer.cpp @@ -1263,6 +1263,7 @@ static CXIdxEntityKind getEntityKindFromSymbolKind(SymbolKind K) { case SymbolKind::CXXTypeAlias: return CXIdxEntity_CXXTypeAlias; case SymbolKind::CXXInterface: return CXIdxEntity_CXXInterface; } + llvm_unreachable("invalid symbol kind"); } static CXIdxEntityCXXTemplateKind @@ -1275,6 +1276,7 @@ getEntityKindFromSymbolCXXTemplateKind(SymbolCXXTemplateKind K) { case SymbolCXXTemplateKind::TemplateSpecialization: return CXIdxEntity_TemplateSpecialization; } + llvm_unreachable("invalid template kind"); } static CXIdxEntityLanguage getEntityLangFromSymbolLang(SymbolLanguage L) { @@ -1283,4 +1285,5 @@ static CXIdxEntityLanguage getEntityLangFromSymbolLang(SymbolLanguage L) { case SymbolLanguage::ObjC: return CXIdxEntityLang_ObjC; case SymbolLanguage::CXX: return CXIdxEntityLang_CXX; } + llvm_unreachable("invalid symbol language"); } diff --git a/unittests/ASTMatchers/ASTMatchersTest.cpp b/unittests/ASTMatchers/ASTMatchersTest.cpp index 5578e066a2..4672fb8f33 100644 --- a/unittests/ASTMatchers/ASTMatchersTest.cpp +++ b/unittests/ASTMatchers/ASTMatchersTest.cpp @@ -1479,6 +1479,14 @@ TEST(IsInteger, ReportsNoFalsePositives) { to(varDecl(hasType(isInteger())))))))); } +TEST(IsAnyPointer, MatchesPointers) { + EXPECT_TRUE(matches("int* i = nullptr;", varDecl(hasType(isAnyPointer())))); +} + +TEST(IsAnyPointer, ReportsNoFalsePositives) { + EXPECT_TRUE(notMatches("int i = 0;", varDecl(hasType(isAnyPointer())))); +} + TEST(IsAnyCharacter, MatchesCharacters) { EXPECT_TRUE(matches("char i = 0;", varDecl(hasType(isAnyCharacter())))); }