[PATCH] D50261: [AST] Remove unnecessary indirections in DeclarationNameTable
This revision was automatically updated to reflect the committed changes. Closed by commit rL339030: [AST] Remove unnecessary indirections in DeclarationNameTable (authored by brunoricci, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D50261?vs=159044&id=159322#toc Repository: rL LLVM https://reviews.llvm.org/D50261 Files: cfe/trunk/include/clang/AST/DeclarationName.h cfe/trunk/lib/AST/DeclarationName.cpp Index: cfe/trunk/lib/AST/DeclarationName.cpp === --- cfe/trunk/lib/AST/DeclarationName.cpp +++ cfe/trunk/lib/AST/DeclarationName.cpp @@ -39,74 +39,6 @@ using namespace clang; -namespace clang { - -/// CXXSpecialName - Records the type associated with one of the -/// "special" kinds of declaration names in C++, e.g., constructors, -/// destructors, and conversion functions. -class CXXSpecialName - : public DeclarationNameExtra, public llvm::FoldingSetNode { -public: - /// Type - The type associated with this declaration name. - QualType Type; - - /// FETokenInfo - Extra information associated with this declaration - /// name that can be used by the front end. - void *FETokenInfo; - - void Profile(llvm::FoldingSetNodeID &ID) { -ID.AddInteger(ExtraKindOrNumArgs); -ID.AddPointer(Type.getAsOpaquePtr()); - } -}; - -/// Contains extra information for the name of a C++ deduction guide. -class CXXDeductionGuideNameExtra : public DeclarationNameExtra, - public llvm::FoldingSetNode { -public: - /// The template named by the deduction guide. - TemplateDecl *Template; - - /// FETokenInfo - Extra information associated with this operator - /// name that can be used by the front end. - void *FETokenInfo; - - void Profile(llvm::FoldingSetNodeID &ID) { -ID.AddPointer(Template); - } -}; - -/// CXXOperatorIdName - Contains extra information for the name of an -/// overloaded operator in C++, such as "operator+. -class CXXOperatorIdName : public DeclarationNameExtra { -public: - /// FETokenInfo - Extra information associated with this operator - /// name that can be used by the front end. - void *FETokenInfo; -}; - -/// CXXLiteralOperatorName - Contains the actual identifier that makes up the -/// name. -/// -/// This identifier is stored here rather than directly in DeclarationName so as -/// to allow Objective-C selectors, which are about a million times more common, -/// to consume minimal memory. -class CXXLiteralOperatorIdName - : public DeclarationNameExtra, public llvm::FoldingSetNode { -public: - IdentifierInfo *ID; - - /// FETokenInfo - Extra information associated with this operator - /// name that can be used by the front end. - void *FETokenInfo; - - void Profile(llvm::FoldingSetNodeID &FSID) { -FSID.AddPointer(ID); - } -}; - -} // namespace clang - static int compareInt(unsigned A, unsigned B) { return (A < B ? -1 : (A > B ? 1 : 0)); } @@ -436,10 +368,6 @@ } DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) { - CXXSpecialNamesImpl = new llvm::FoldingSet; - CXXLiteralOperatorNames = new llvm::FoldingSet; - CXXDeductionGuideNames = new llvm::FoldingSet; - // Initialize the overloaded operator names. CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS]; for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) { @@ -449,21 +377,6 @@ } } -DeclarationNameTable::~DeclarationNameTable() { - auto *SpecialNames = - static_cast *>(CXXSpecialNamesImpl); - auto *LiteralNames = - static_cast *>( - CXXLiteralOperatorNames); - auto *DeductionGuideNames = - static_cast *>( - CXXDeductionGuideNames); - - delete SpecialNames; - delete LiteralNames; - delete DeductionGuideNames; -} - DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) { return getCXXSpecialName(DeclarationName::CXXConstructorName, Ty.getUnqualifiedType()); @@ -478,23 +391,19 @@ DeclarationNameTable::getCXXDeductionGuideName(TemplateDecl *Template) { Template = cast(Template->getCanonicalDecl()); - auto *DeductionGuideNames = - static_cast *>( - CXXDeductionGuideNames); - llvm::FoldingSetNodeID ID; ID.AddPointer(Template); void *InsertPos = nullptr; - if (auto *Name = DeductionGuideNames->FindNodeOrInsertPos(ID, InsertPos)) + if (auto *Name = CXXDeductionGuideNames.FindNodeOrInsertPos(ID, InsertPos)) return DeclarationName(Name); auto *Name = new (Ctx) CXXDeductionGuideNameExtra; Name->ExtraKindOrNumArgs = DeclarationNameExtra::CXXDeductionGuide; Name->Template = Template; Name->FETokenInfo = nullptr; - DeductionGuideNames->InsertNode(Name, InsertPos); + CXXDeductionGuideNames.InsertNode(Name, InsertPos); return DeclarationName(Name); } @@ -509,8 +418,6 @@ assert(Kind >= DeclarationName::CXXConstructorName && Kind
[PATCH] D49627: [CFG] [analyzer] Constructors of member CXXOperatorCallExpr's argument 0 are not argument constructors.
This revision was automatically updated to reflect the committed changes. Closed by commit rC339087: [analyzer] NFC: Document that we support implicit argument constructors. (authored by dergachev, committed by ). Repository: rC Clang https://reviews.llvm.org/D49627 Files: include/clang/Analysis/ConstructionContext.h test/Analysis/cfg-rich-constructors.cpp test/Analysis/temporaries.cpp Index: include/clang/Analysis/ConstructionContext.h === --- include/clang/Analysis/ConstructionContext.h +++ include/clang/Analysis/ConstructionContext.h @@ -623,9 +623,16 @@ }; class ArgumentConstructionContext : public ConstructionContext { - const Expr *CE; // The call of which the context is an argument. - unsigned Index; // Which argument we're constructing. - const CXXBindTemporaryExpr *BTE; // Whether the object needs to be destroyed. + // The call of which the context is an argument. + const Expr *CE; + + // Which argument we're constructing. Note that when numbering between + // arguments and parameters is inconsistent (eg., operator calls), + // this is the index of the argument, not of the parameter. + unsigned Index; + + // Whether the object needs to be destroyed. + const CXXBindTemporaryExpr *BTE; friend class ConstructionContext; // Allows to create<>() itself. Index: test/Analysis/temporaries.cpp === --- test/Analysis/temporaries.cpp +++ test/Analysis/temporaries.cpp @@ -986,3 +986,21 @@ *i = 99; // no-warning } } // namespace ctor_argument + +namespace operator_implicit_argument { +struct S { + bool x; + S(bool x): x(x) {} + operator bool() const { return x; } +}; + +void foo() { + if (S(false)) { +clang_analyzer_warnIfReached(); // no-warning + } + if (S(true)) { +clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} + } +} +} // namespace operator_implicit_argument + Index: test/Analysis/cfg-rich-constructors.cpp === --- test/Analysis/cfg-rich-constructors.cpp +++ test/Analysis/cfg-rich-constructors.cpp @@ -963,3 +963,35 @@ C c = C(); } } // namespace copy_elision_with_extra_arguments + + +namespace operators { +class C { +public: + C(int); + C &operator+(C Other); +}; + +// FIXME: Find construction context for the this-argument of the operator. +// CHECK: void testOperators() +// CHECK:[B1] +// CHECK-NEXT: 1: operator+ +// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class operators::C &(*)(class o +// CHECK-NEXT: 3: 1 +// CHECK-NEXT: 4: [B1.3] (CXXConstructExpr, [B1.6], class operators::C) +// CHECK-NEXT: 5: operators::C([B1.4]) (CXXFunctionalCastExpr, ConstructorConversion, class operato +// CHECK-NEXT: 6: [B1.5] +// CHECK-NEXT: 7: 2 +// CXX11-ELIDE-NEXT: 8: [B1.7] (CXXConstructExpr, [B1.10], [B1.11], class operators::C) +// CXX11-NOELIDE-NEXT: 8: [B1.7] (CXXConstructExpr, [B1.10], class operators::C) +// CXX11-NEXT: 9: operators::C([B1.8]) (CXXFunctionalCastExpr, ConstructorConversion, class operato +// CXX11-NEXT:10: [B1.9] +// CXX11-NEXT:11: [B1.10] (CXXConstructExpr, [B1.12]+1, class operators::C) +// CXX11-NEXT:12: [B1.6] + [B1.11] (OperatorCall) +// CXX17-NEXT: 8: [B1.7] (CXXConstructExpr, [B1.10]+1, class operators::C) +// CXX17-NEXT: 9: operators::C([B1.8]) (CXXFunctionalCastExpr, ConstructorConversion, class operato +// CXX17-NEXT:10: [B1.6] + [B1.9] (OperatorCall) +void testOperators() { + C(1) + C(2); +} +} // namespace operators Index: include/clang/Analysis/ConstructionContext.h === --- include/clang/Analysis/ConstructionContext.h +++ include/clang/Analysis/ConstructionContext.h @@ -623,9 +623,16 @@ }; class ArgumentConstructionContext : public ConstructionContext { - const Expr *CE; // The call of which the context is an argument. - unsigned Index; // Which argument we're constructing. - const CXXBindTemporaryExpr *BTE; // Whether the object needs to be destroyed. + // The call of which the context is an argument. + const Expr *CE; + + // Which argument we're constructing. Note that when numbering between + // arguments and parameters is inconsistent (eg., operator calls), + // this is the index of the argument, not of the parameter. + unsigned Index; + + // Whether the object needs to be destroyed. + const CXXBindTemporaryExpr *BTE; friend class ConstructionContext; // Allows to create<>() itself. Index: test/Analysis/temporaries.cpp === --- test/Analysis/temporaries.cpp +++ test/Analysis/temporaries.cpp @@ -986,3 +986,21 @@ *i = 99; // no-warning } } // namespace ctor_argument + +namespace operator_implicit_argument { +struct S { + bool x; + S(bool x): x(x) {} + operator b
[PATCH] D50363: [analyzer] pr37204: Take signedness into account in BasicValueFactory::getTruthValue().
This revision was automatically updated to reflect the committed changes. Closed by commit rC339088: [analyzer] pr37204: Take signedness into account in getTruthValue(). (authored by dergachev, committed by ). Changed prior to commit: https://reviews.llvm.org/D50363?vs=159435&id=159446#toc Repository: rC Clang https://reviews.llvm.org/D50363 Files: include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h test/Analysis/casts.c Index: include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h === --- include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h +++ include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h @@ -211,7 +211,8 @@ } const llvm::APSInt &getTruthValue(bool b, QualType T) { -return getValue(b ? 1 : 0, Ctx.getIntWidth(T), true); +return getValue(b ? 1 : 0, Ctx.getIntWidth(T), +T->isUnsignedIntegerOrEnumerationType()); } const llvm::APSInt &getTruthValue(bool b) { Index: test/Analysis/casts.c === --- test/Analysis/casts.c +++ test/Analysis/casts.c @@ -182,3 +182,9 @@ c += 1; } } + +void testSwitchWithSizeofs() { + switch (sizeof(char) == 1) { // expected-warning{{switch condition has boolean value}} + case sizeof(char):; // no-crash + } +} Index: include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h === --- include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h +++ include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h @@ -211,7 +211,8 @@ } const llvm::APSInt &getTruthValue(bool b, QualType T) { -return getValue(b ? 1 : 0, Ctx.getIntWidth(T), true); +return getValue(b ? 1 : 0, Ctx.getIntWidth(T), +T->isUnsignedIntegerOrEnumerationType()); } const llvm::APSInt &getTruthValue(bool b) { Index: test/Analysis/casts.c === --- test/Analysis/casts.c +++ test/Analysis/casts.c @@ -182,3 +182,9 @@ c += 1; } } + +void testSwitchWithSizeofs() { + switch (sizeof(char) == 1) { // expected-warning{{switch condition has boolean value}} + case sizeof(char):; // no-crash + } +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D50395: [WebAssembly] Remove use of lld -flavor flag
This revision was automatically updated to reflect the committed changes. Closed by commit rL339163: [WebAssembly] Remove use of lld -flavor flag (authored by sbc, committed by ). Herald added a subscriber: llvm-commits. Repository: rL LLVM https://reviews.llvm.org/D50395 Files: cfe/trunk/lib/Driver/ToolChains/WebAssembly.cpp cfe/trunk/lib/Driver/ToolChains/WebAssembly.h cfe/trunk/test/Driver/wasm-toolchain.c cfe/trunk/test/Driver/wasm-toolchain.cpp Index: cfe/trunk/lib/Driver/ToolChains/WebAssembly.h === --- cfe/trunk/lib/Driver/ToolChains/WebAssembly.h +++ cfe/trunk/lib/Driver/ToolChains/WebAssembly.h @@ -66,9 +66,7 @@ llvm::opt::ArgStringList &CmdArgs) const override; std::string getThreadModel() const override; - const char *getDefaultLinker() const override { -return "lld"; - } + const char *getDefaultLinker() const override { return "wasm-ld"; } Tool *buildLinker() const override; }; Index: cfe/trunk/lib/Driver/ToolChains/WebAssembly.cpp === --- cfe/trunk/lib/Driver/ToolChains/WebAssembly.cpp +++ cfe/trunk/lib/Driver/ToolChains/WebAssembly.cpp @@ -41,8 +41,6 @@ const ToolChain &ToolChain = getToolChain(); const char *Linker = Args.MakeArgString(ToolChain.GetLinkerPath()); ArgStringList CmdArgs; - CmdArgs.push_back("-flavor"); - CmdArgs.push_back("wasm"); if (Args.hasArg(options::OPT_s)) CmdArgs.push_back("--strip-all"); Index: cfe/trunk/test/Driver/wasm-toolchain.c === --- cfe/trunk/test/Driver/wasm-toolchain.c +++ cfe/trunk/test/Driver/wasm-toolchain.c @@ -12,12 +12,12 @@ // A basic C link command-line. -// RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo -fuse-ld=lld %s 2>&1 | FileCheck -check-prefix=LINK %s +// RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo -fuse-ld=wasm-ld %s 2>&1 | FileCheck -check-prefix=LINK %s // LINK: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]" -// LINK: lld{{.*}}" "-flavor" "wasm" "-L/foo/lib" "crt1.o" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out" +// LINK: wasm-ld{{.*}}" "-L/foo/lib" "crt1.o" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out" // A basic C link command-line with optimization. -// RUN: %clang -### -O2 -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo -fuse-ld=lld %s 2>&1 | FileCheck -check-prefix=LINK_OPT %s +// RUN: %clang -### -O2 -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo -fuse-ld=wasm-ld %s 2>&1 | FileCheck -check-prefix=LINK_OPT %s // LINK_OPT: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]" -// LINK_OPT: lld{{.*}}" "-flavor" "wasm" "-L/foo/lib" "crt1.o" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out" +// LINK_OPT: wasm-ld{{.*}}" "-L/foo/lib" "crt1.o" "[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out" Index: cfe/trunk/test/Driver/wasm-toolchain.cpp === --- cfe/trunk/test/Driver/wasm-toolchain.cpp +++ cfe/trunk/test/Driver/wasm-toolchain.cpp @@ -12,12 +12,12 @@ // A basic C++ link command-line. -// RUN: %clangxx -### -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo --stdlib=c++ -fuse-ld=lld %s 2>&1 | FileCheck -check-prefix=LINK %s +// RUN: %clangxx -### -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo --stdlib=c++ -fuse-ld=wasm-ld %s 2>&1 | FileCheck -check-prefix=LINK %s // LINK: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]" -// LINK: lld{{.*}}" "-flavor" "wasm" "-L/foo/lib" "crt1.o" "[[temp]]" "-lc++" "-lc++abi" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out" +// LINK: wasm-ld{{.*}}" "-L/foo/lib" "crt1.o" "[[temp]]" "-lc++" "-lc++abi" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out" // A basic C++ link command-line with optimization. -// RUN: %clangxx -### -O2 -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo %s --stdlib=c++ -fuse-ld=lld 2>&1 | FileCheck -check-prefix=LINK_OPT %s +// RUN: %clangxx -### -O2 -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo %s --stdlib=c++ -fuse-ld=wasm-ld 2>&1 | FileCheck -check-prefix=LINK_OPT %s // LINK_OPT: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]" -// LINK_OPT: lld{{.*}}" "-flavor" "wasm" "-L/foo/lib" "crt1.o" "[[temp]]" "-lc++" "-lc++abi" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out" +// LINK_OPT: wasm-ld{{.*}}" "-L/foo/lib" "crt1.o" "[[temp]]" "-lc++" "-lc++abi" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out" Index: cfe/trunk/lib/Driver/ToolChains/WebAssembly.h === --- cfe/trunk/lib/Driver/ToolChains/WebAssembly
[PATCH] D50088: [Sema] Fix an error with C++17 auto non-type template parameters
This revision was automatically updated to reflect the committed changes. Closed by commit rL339198: [Sema] Ensure an auto non-type template parameter is dependent (authored by epilk, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D50088?vs=159449&id=159613#toc Repository: rL LLVM https://reviews.llvm.org/D50088 Files: cfe/trunk/lib/Sema/SemaTemplate.cpp cfe/trunk/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp Index: cfe/trunk/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp === --- cfe/trunk/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp +++ cfe/trunk/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp @@ -335,3 +335,46 @@ void g(int, int); using Int = A::B<&g>::param2; } + +namespace rdar41852459 { +template struct G {}; + +template struct S { + template void f() { +G x; + } + template void f2() { +G x; + } + template void f3() { +G x; + } +}; + +template struct I {}; + +template struct K { + template void f() { +I x; + } + template void f2() { +I x; + } + template void f3() { +I x; + } +}; + +template struct L {}; +template struct M { + template void f() { +L x; + } + template void f() { +L x; + } + template void f() { +L x; + } +}; +} Index: cfe/trunk/lib/Sema/SemaTemplate.cpp === --- cfe/trunk/lib/Sema/SemaTemplate.cpp +++ cfe/trunk/lib/Sema/SemaTemplate.cpp @@ -974,7 +974,7 @@ QualType Sema::CheckNonTypeTemplateParameterType(TypeSourceInfo *&TSI, SourceLocation Loc) { if (TSI->getType()->isUndeducedType()) { -// C++1z [temp.dep.expr]p3: +// C++17 [temp.dep.expr]p3: // An id-expression is type-dependent if it contains //- an identifier associated by name lookup with a non-type // template-parameter declared with a type that contains a @@ -9866,6 +9866,15 @@ if (!NewTSI) return true; +if (NewTSI->getType()->isUndeducedType()) { + // C++17 [temp.dep.expr]p3: + // An id-expression is type-dependent if it contains + //- an identifier associated by name lookup with a non-type + // template-parameter declared with a type that contains a + // placeholder type (7.1.7.4), + NewTSI = SubstAutoTypeSourceInfo(NewTSI, Context.DependentTy); +} + if (NewTSI != NTTP->getTypeSourceInfo()) { NTTP->setTypeSourceInfo(NewTSI); NTTP->setType(NewTSI->getType()); Index: cfe/trunk/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp === --- cfe/trunk/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp +++ cfe/trunk/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp @@ -335,3 +335,46 @@ void g(int, int); using Int = A::B<&g>::param2; } + +namespace rdar41852459 { +template struct G {}; + +template struct S { + template void f() { +G x; + } + template void f2() { +G x; + } + template void f3() { +G x; + } +}; + +template struct I {}; + +template struct K { + template void f() { +I x; + } + template void f2() { +I x; + } + template void f3() { +I x; + } +}; + +template struct L {}; +template struct M { + template void f() { +L x; + } + template void f() { +L x; + } + template void f() { +L x; + } +}; +} Index: cfe/trunk/lib/Sema/SemaTemplate.cpp === --- cfe/trunk/lib/Sema/SemaTemplate.cpp +++ cfe/trunk/lib/Sema/SemaTemplate.cpp @@ -974,7 +974,7 @@ QualType Sema::CheckNonTypeTemplateParameterType(TypeSourceInfo *&TSI, SourceLocation Loc) { if (TSI->getType()->isUndeducedType()) { -// C++1z [temp.dep.expr]p3: +// C++17 [temp.dep.expr]p3: // An id-expression is type-dependent if it contains //- an identifier associated by name lookup with a non-type // template-parameter declared with a type that contains a @@ -9866,6 +9866,15 @@ if (!NewTSI) return true; +if (NewTSI->getType()->isUndeducedType()) { + // C++17 [temp.dep.expr]p3: + // An id-expression is type-dependent if it contains + //- an identifier associated by name lookup with a non-type + // template-parameter declared with a type that contains a + // placeholder type (7.1.7.4), + NewTSI = SubstAutoTypeSourceInfo(NewTSI, Context.DependentTy); +} + if (NewTSI != NTTP->getTypeSourceInfo()) { NTTP->setTypeSourceInfo(NewTSI); NTTP->setType(NewTSI->getType()); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D50088: [Sema] Fix an error with C++17 auto non-type template parameters
This revision was automatically updated to reflect the committed changes. Closed by commit rC339198: [Sema] Ensure an auto non-type template parameter is dependent (authored by epilk, committed by ). Changed prior to commit: https://reviews.llvm.org/D50088?vs=159449&id=159612#toc Repository: rL LLVM https://reviews.llvm.org/D50088 Files: lib/Sema/SemaTemplate.cpp test/SemaTemplate/temp_arg_nontype_cxx1z.cpp Index: test/SemaTemplate/temp_arg_nontype_cxx1z.cpp === --- test/SemaTemplate/temp_arg_nontype_cxx1z.cpp +++ test/SemaTemplate/temp_arg_nontype_cxx1z.cpp @@ -335,3 +335,46 @@ void g(int, int); using Int = A::B<&g>::param2; } + +namespace rdar41852459 { +template struct G {}; + +template struct S { + template void f() { +G x; + } + template void f2() { +G x; + } + template void f3() { +G x; + } +}; + +template struct I {}; + +template struct K { + template void f() { +I x; + } + template void f2() { +I x; + } + template void f3() { +I x; + } +}; + +template struct L {}; +template struct M { + template void f() { +L x; + } + template void f() { +L x; + } + template void f() { +L x; + } +}; +} Index: lib/Sema/SemaTemplate.cpp === --- lib/Sema/SemaTemplate.cpp +++ lib/Sema/SemaTemplate.cpp @@ -974,7 +974,7 @@ QualType Sema::CheckNonTypeTemplateParameterType(TypeSourceInfo *&TSI, SourceLocation Loc) { if (TSI->getType()->isUndeducedType()) { -// C++1z [temp.dep.expr]p3: +// C++17 [temp.dep.expr]p3: // An id-expression is type-dependent if it contains //- an identifier associated by name lookup with a non-type // template-parameter declared with a type that contains a @@ -9866,6 +9866,15 @@ if (!NewTSI) return true; +if (NewTSI->getType()->isUndeducedType()) { + // C++17 [temp.dep.expr]p3: + // An id-expression is type-dependent if it contains + //- an identifier associated by name lookup with a non-type + // template-parameter declared with a type that contains a + // placeholder type (7.1.7.4), + NewTSI = SubstAutoTypeSourceInfo(NewTSI, Context.DependentTy); +} + if (NewTSI != NTTP->getTypeSourceInfo()) { NTTP->setTypeSourceInfo(NewTSI); NTTP->setType(NewTSI->getType()); Index: test/SemaTemplate/temp_arg_nontype_cxx1z.cpp === --- test/SemaTemplate/temp_arg_nontype_cxx1z.cpp +++ test/SemaTemplate/temp_arg_nontype_cxx1z.cpp @@ -335,3 +335,46 @@ void g(int, int); using Int = A::B<&g>::param2; } + +namespace rdar41852459 { +template struct G {}; + +template struct S { + template void f() { +G x; + } + template void f2() { +G x; + } + template void f3() { +G x; + } +}; + +template struct I {}; + +template struct K { + template void f() { +I x; + } + template void f2() { +I x; + } + template void f3() { +I x; + } +}; + +template struct L {}; +template struct M { + template void f() { +L x; + } + template void f() { +L x; + } + template void f() { +L x; + } +}; +} Index: lib/Sema/SemaTemplate.cpp === --- lib/Sema/SemaTemplate.cpp +++ lib/Sema/SemaTemplate.cpp @@ -974,7 +974,7 @@ QualType Sema::CheckNonTypeTemplateParameterType(TypeSourceInfo *&TSI, SourceLocation Loc) { if (TSI->getType()->isUndeducedType()) { -// C++1z [temp.dep.expr]p3: +// C++17 [temp.dep.expr]p3: // An id-expression is type-dependent if it contains //- an identifier associated by name lookup with a non-type // template-parameter declared with a type that contains a @@ -9866,6 +9866,15 @@ if (!NewTSI) return true; +if (NewTSI->getType()->isUndeducedType()) { + // C++17 [temp.dep.expr]p3: + // An id-expression is type-dependent if it contains + //- an identifier associated by name lookup with a non-type + // template-parameter declared with a type that contains a + // placeholder type (7.1.7.4), + NewTSI = SubstAutoTypeSourceInfo(NewTSI, Context.DependentTy); +} + if (NewTSI != NTTP->getTypeSourceInfo()) { NTTP->setTypeSourceInfo(NewTSI); NTTP->setType(NewTSI->getType()); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D50412: [libunwind] Fix pointer-to-integer cast warnings on LLP64.
This revision was automatically updated to reflect the committed changes. Closed by commit rL339217: [libunwind] Fix pointer-to-integer cast warnings on LLP64. (authored by cdavis, committed by ). Repository: rL LLVM https://reviews.llvm.org/D50412 Files: libunwind/trunk/src/UnwindLevel1-gcc-ext.c libunwind/trunk/src/UnwindLevel1.c Index: libunwind/trunk/src/UnwindLevel1-gcc-ext.c === --- libunwind/trunk/src/UnwindLevel1-gcc-ext.c +++ libunwind/trunk/src/UnwindLevel1-gcc-ext.c @@ -33,9 +33,9 @@ (void *)exception_object, (long)exception_object->unwinder_cache.reserved1); #else - _LIBUNWIND_TRACE_API("_Unwind_Resume_or_Rethrow(ex_obj=%p), private_1=%ld", + _LIBUNWIND_TRACE_API("_Unwind_Resume_or_Rethrow(ex_obj=%p), private_1=%" PRIdPTR, (void *)exception_object, - (long)exception_object->private_1); + (intptr_t)exception_object->private_1); #endif #if defined(_LIBUNWIND_ARM_EHABI) @@ -92,9 +92,9 @@ unw_proc_info_t info; unw_getcontext(&uc); unw_init_local(&cursor, &uc); - unw_set_reg(&cursor, UNW_REG_IP, (unw_word_t)(long) pc); + unw_set_reg(&cursor, UNW_REG_IP, (unw_word_t)(intptr_t) pc); if (unw_get_proc_info(&cursor, &info) == UNW_ESUCCESS) -return (void *)(long) info.start_ip; +return (void *)(intptr_t) info.start_ip; else return NULL; } @@ -190,14 +190,14 @@ unw_proc_info_t info; unw_getcontext(&uc); unw_init_local(&cursor, &uc); - unw_set_reg(&cursor, UNW_REG_IP, (unw_word_t)(long) pc); + unw_set_reg(&cursor, UNW_REG_IP, (unw_word_t)(intptr_t) pc); unw_get_proc_info(&cursor, &info); bases->tbase = (uintptr_t)info.extra; bases->dbase = 0; // dbase not used on Mac OS X bases->func = (uintptr_t)info.start_ip; _LIBUNWIND_TRACE_API("_Unwind_Find_FDE(pc=%p) => %p", pc, - (void *)(long) info.unwind_info); - return (void *)(long) info.unwind_info; + (void *)(intptr_t) info.unwind_info); + return (void *)(intptr_t) info.unwind_info; } /// Returns the CFA (call frame area, or stack pointer at start of function) Index: libunwind/trunk/src/UnwindLevel1.c === --- libunwind/trunk/src/UnwindLevel1.c +++ libunwind/trunk/src/UnwindLevel1.c @@ -287,7 +287,7 @@ // If there is a personality routine, tell it we are unwinding. if (frameInfo.handler != 0) { __personality_routine p = - (__personality_routine)(long)(frameInfo.handler); + (__personality_routine)(intptr_t)(frameInfo.handler); _LIBUNWIND_TRACE_UNWINDING( "unwind_phase2_forced(ex_ojb=%p): calling personality function %p", (void *)exception_object, (void *)(uintptr_t)p); Index: libunwind/trunk/src/UnwindLevel1-gcc-ext.c === --- libunwind/trunk/src/UnwindLevel1-gcc-ext.c +++ libunwind/trunk/src/UnwindLevel1-gcc-ext.c @@ -33,9 +33,9 @@ (void *)exception_object, (long)exception_object->unwinder_cache.reserved1); #else - _LIBUNWIND_TRACE_API("_Unwind_Resume_or_Rethrow(ex_obj=%p), private_1=%ld", + _LIBUNWIND_TRACE_API("_Unwind_Resume_or_Rethrow(ex_obj=%p), private_1=%" PRIdPTR, (void *)exception_object, - (long)exception_object->private_1); + (intptr_t)exception_object->private_1); #endif #if defined(_LIBUNWIND_ARM_EHABI) @@ -92,9 +92,9 @@ unw_proc_info_t info; unw_getcontext(&uc); unw_init_local(&cursor, &uc); - unw_set_reg(&cursor, UNW_REG_IP, (unw_word_t)(long) pc); + unw_set_reg(&cursor, UNW_REG_IP, (unw_word_t)(intptr_t) pc); if (unw_get_proc_info(&cursor, &info) == UNW_ESUCCESS) -return (void *)(long) info.start_ip; +return (void *)(intptr_t) info.start_ip; else return NULL; } @@ -190,14 +190,14 @@ unw_proc_info_t info; unw_getcontext(&uc); unw_init_local(&cursor, &uc); - unw_set_reg(&cursor, UNW_REG_IP, (unw_word_t)(long) pc); + unw_set_reg(&cursor, UNW_REG_IP, (unw_word_t)(intptr_t) pc); unw_get_proc_info(&cursor, &info); bases->tbase = (uintptr_t)info.extra; bases->dbase = 0; // dbase not used on Mac OS X bases->func = (uintptr_t)info.start_ip; _LIBUNWIND_TRACE_API("_Unwind_Find_FDE(pc=%p) => %p", pc, - (void *)(long) info.unwind_info); - return (void *)(long) info.unwind_info; + (void *)(intptr_t) info.unwind_info); + return (void *)(intptr_t) info.unwind_info; } /// Returns the CFA (call frame area, or stack pointer at start of function) Index: libunwind/trunk/src/UnwindLevel1.c === --- libunwind/trunk/src/UnwindLevel1.c +++ libunwind/trunk/src/UnwindLevel1.c @@ -287,7 +287,7 @@ // If there is
[PATCH] D50382: [analyzer] Fix a typo in `RegionStore.txt`.
This revision was automatically updated to reflect the committed changes. Closed by commit rL339244: [analyzer] Fix a typo in `RegionStore.txt`. (authored by henrywong, committed by ). Herald added a subscriber: llvm-commits. Repository: rL LLVM https://reviews.llvm.org/D50382 Files: cfe/trunk/docs/analyzer/RegionStore.txt Index: cfe/trunk/docs/analyzer/RegionStore.txt === --- cfe/trunk/docs/analyzer/RegionStore.txt +++ cfe/trunk/docs/analyzer/RegionStore.txt @@ -118,7 +118,7 @@ int manyInts[10]; manyInts[1] = 42; // Creates a Direct binding for manyInts[1]. print(manyInts[1]); // Retrieves the Direct binding for manyInts[1]; - print(manyInts[0]); // There is no Direct binding for manyInts[1]. + print(manyInts[0]); // There is no Direct binding for manyInts[0]. // Is there a Default binding for the entire array? // There is not, but it is a stack variable, so we use // "uninitialized" as the default value (and emit a @@ -166,6 +166,6 @@ return p2.x;// The binding for FieldRegion 'p2.x' is requested. // There is no Direct binding, so we look for a Default // binding to 'p2' and find the LCV. -// Because it's an LCV, we look at our requested region +// Because it's a LCV, we look at our requested region // and see that it's the '.x' field. We ask for the value // of 'p.x' within the snapshot, and get back 42. Index: cfe/trunk/docs/analyzer/RegionStore.txt === --- cfe/trunk/docs/analyzer/RegionStore.txt +++ cfe/trunk/docs/analyzer/RegionStore.txt @@ -118,7 +118,7 @@ int manyInts[10]; manyInts[1] = 42; // Creates a Direct binding for manyInts[1]. print(manyInts[1]); // Retrieves the Direct binding for manyInts[1]; - print(manyInts[0]); // There is no Direct binding for manyInts[1]. + print(manyInts[0]); // There is no Direct binding for manyInts[0]. // Is there a Default binding for the entire array? // There is not, but it is a stack variable, so we use // "uninitialized" as the default value (and emit a @@ -166,6 +166,6 @@ return p2.x;// The binding for FieldRegion 'p2.x' is requested. // There is no Direct binding, so we look for a Default // binding to 'p2' and find the LCV. -// Because it's an LCV, we look at our requested region +// Because it's a LCV, we look at our requested region // and see that it's the '.x' field. We ask for the value // of 'p.x' within the snapshot, and get back 42. ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D50414: [libunwind][include] Add SEH declarations to .
This revision was automatically updated to reflect the committed changes. Closed by commit rL339258: [libunwind][include] Add SEH declarations to. (authored by cdavis, committed by ). Changed prior to commit: https://reviews.llvm.org/D50414?vs=159722&id=159728#toc Repository: rL LLVM https://reviews.llvm.org/D50414 Files: libunwind/trunk/include/unwind.h Index: libunwind/trunk/include/unwind.h === --- libunwind/trunk/include/unwind.h +++ libunwind/trunk/include/unwind.h @@ -19,6 +19,10 @@ #include #include +#if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__) +#include +#endif + #if defined(__APPLE__) #define LIBUNWIND_UNAVAIL __attribute__ (( unavailable )) #else @@ -120,13 +124,17 @@ uint64_t exception_class; void (*exception_cleanup)(_Unwind_Reason_Code reason, _Unwind_Exception *exc); +#if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__) + uintptr_t private_[6]; +#else uintptr_t private_1; // non-zero means forced unwind uintptr_t private_2; // holds sp that phase1 found for phase2 to use +#endif #if __SIZEOF_POINTER__ == 4 // The implementation of _Unwind_Exception uses an attribute mode on the // above fields which has the side effect of causing this whole struct to - // round up to 32 bytes in size. To be more explicit, we add pad fields - // added for binary compatibility. + // round up to 32 bytes in size (48 with SEH). To be more explicit, we add + // pad fields added for binary compatibility. uint32_t reserved[3]; #endif // The Itanium ABI requires that _Unwind_Exception objects are "double-word @@ -369,6 +377,24 @@ extern void *__deregister_frame_info_bases(const void *fde) LIBUNWIND_UNAVAIL; +#if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__) +// This is the common wrapper for GCC-style personality functions with SEH. +#ifdef __x86_64__ +// The DISPATCHER_CONTEXT struct is only defined on x64. +extern EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD exc, + PVOID frame, + PCONTEXT ctx, + PDISPATCHER_CONTEXT disp, + _Unwind_Personality_Fn pers); +#else +extern EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD exc, + PVOID frame, + PCONTEXT ctx, + PVOID disp, + _Unwind_Personality_Fn pers); +#endif +#endif + #ifdef __cplusplus } #endif Index: libunwind/trunk/include/unwind.h === --- libunwind/trunk/include/unwind.h +++ libunwind/trunk/include/unwind.h @@ -19,6 +19,10 @@ #include #include +#if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__) +#include +#endif + #if defined(__APPLE__) #define LIBUNWIND_UNAVAIL __attribute__ (( unavailable )) #else @@ -120,13 +124,17 @@ uint64_t exception_class; void (*exception_cleanup)(_Unwind_Reason_Code reason, _Unwind_Exception *exc); +#if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__) + uintptr_t private_[6]; +#else uintptr_t private_1; // non-zero means forced unwind uintptr_t private_2; // holds sp that phase1 found for phase2 to use +#endif #if __SIZEOF_POINTER__ == 4 // The implementation of _Unwind_Exception uses an attribute mode on the // above fields which has the side effect of causing this whole struct to - // round up to 32 bytes in size. To be more explicit, we add pad fields - // added for binary compatibility. + // round up to 32 bytes in size (48 with SEH). To be more explicit, we add + // pad fields added for binary compatibility. uint32_t reserved[3]; #endif // The Itanium ABI requires that _Unwind_Exception objects are "double-word @@ -369,6 +377,24 @@ extern void *__deregister_frame_info_bases(const void *fde) LIBUNWIND_UNAVAIL; +#if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__) +// This is the common wrapper for GCC-style personality functions with SEH. +#ifdef __x86_64__ +// The DISPATCHER_CONTEXT struct is only defined on x64. +extern EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD exc, + PVOID frame, + PCONTEXT ctx, + PDISPATCHER_CONTEXT disp, + _Unwind_Personality_Fn pers); +#else +extern EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD exc, + PVOID frame, +
[PATCH] D50168: [Builtins] Implement __builtin_clrsb to be compatible with gcc
This revision was automatically updated to reflect the committed changes. Closed by commit rC339282: [Builtins] Implement __builtin_clrsb to be compatible with gcc (authored by ctopper, committed by ). Herald added a subscriber: kristina. Repository: rC Clang https://reviews.llvm.org/D50168 Files: include/clang/Basic/Builtins.def lib/CodeGen/CGBuiltin.cpp test/CodeGen/builtin_clrsb.c Index: include/clang/Basic/Builtins.def === --- include/clang/Basic/Builtins.def +++ include/clang/Basic/Builtins.def @@ -413,6 +413,9 @@ BUILTIN(__builtin_popcount , "iUi" , "nc") BUILTIN(__builtin_popcountl , "iULi" , "nc") BUILTIN(__builtin_popcountll, "iULLi", "nc") +BUILTIN(__builtin_clrsb , "ii" , "nc") +BUILTIN(__builtin_clrsbl , "iLi" , "nc") +BUILTIN(__builtin_clrsbll, "iLLi", "nc") // FIXME: These type signatures are not correct for targets with int != 32-bits // or with ULL != 64-bits. Index: test/CodeGen/builtin_clrsb.c === --- test/CodeGen/builtin_clrsb.c +++ test/CodeGen/builtin_clrsb.c @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +int test__builtin_clrsb(int x) { +// CHECK-LABEL: test__builtin_clrsb +// CHECK: [[C:%.*]] = icmp slt i32 [[X:%.*]], 0 +// CHECK-NEXT: [[INV:%.*]] = xor i32 [[X]], -1 +// CHECK-NEXT: [[SEL:%.*]] = select i1 [[C]], i32 [[INV]], i32 [[X]] +// CHECK-NEXT: [[CTLZ:%.*]] = call i32 @llvm.ctlz.i32(i32 [[SEL]], i1 false) +// CHECK-NEXT: [[SUB:%.*]] = sub i32 [[CTLZ]], 1 + return __builtin_clrsb(x); +} + +int test__builtin_clrsbll(long long x) { +// CHECK-LABEL: test__builtin_clrsbll +// CHECK: [[C:%.*]] = icmp slt i64 [[X:%.*]], 0 +// CHECK-NEXT: [[INV:%.*]] = xor i64 [[X]], -1 +// CHECK-NEXT: [[SEL:%.*]] = select i1 [[C]], i64 [[INV]], i64 [[X]] +// CHECK-NEXT: [[CTLZ:%.*]] = call i64 @llvm.ctlz.i64(i64 [[SEL]], i1 false) +// CHECK-NEXT: [[SUB:%.*]] = sub i64 [[CTLZ]], 1 +// CHECK-NEXT: trunc i64 [[SUB]] to i32 + return __builtin_clrsbll(x); +} Index: lib/CodeGen/CGBuiltin.cpp === --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -1537,6 +1537,26 @@ return RValue::get(ComplexVal.second); } + case Builtin::BI__builtin_clrsb: + case Builtin::BI__builtin_clrsbl: + case Builtin::BI__builtin_clrsbll: { +// clrsb(x) -> clz(x < 0 ? ~x : x) - 1 or +Value *ArgValue = EmitScalarExpr(E->getArg(0)); + +llvm::Type *ArgType = ArgValue->getType(); +Value *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType); + +llvm::Type *ResultType = ConvertType(E->getType()); +Value *Zero = llvm::Constant::getNullValue(ArgType); +Value *IsNeg = Builder.CreateICmpSLT(ArgValue, Zero, "isneg"); +Value *Inverse = Builder.CreateNot(ArgValue, "not"); +Value *Tmp = Builder.CreateSelect(IsNeg, Inverse, ArgValue); +Value *Ctlz = Builder.CreateCall(F, {Tmp, Builder.getFalse()}); +Value *Result = Builder.CreateSub(Ctlz, llvm::ConstantInt::get(ArgType, 1)); +Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, + "cast"); +return RValue::get(Result); + } case Builtin::BI__builtin_ctzs: case Builtin::BI__builtin_ctz: case Builtin::BI__builtin_ctzl: Index: include/clang/Basic/Builtins.def === --- include/clang/Basic/Builtins.def +++ include/clang/Basic/Builtins.def @@ -413,6 +413,9 @@ BUILTIN(__builtin_popcount , "iUi" , "nc") BUILTIN(__builtin_popcountl , "iULi" , "nc") BUILTIN(__builtin_popcountll, "iULLi", "nc") +BUILTIN(__builtin_clrsb , "ii" , "nc") +BUILTIN(__builtin_clrsbl , "iLi" , "nc") +BUILTIN(__builtin_clrsbll, "iLLi", "nc") // FIXME: These type signatures are not correct for targets with int != 32-bits // or with ULL != 64-bits. Index: test/CodeGen/builtin_clrsb.c === --- test/CodeGen/builtin_clrsb.c +++ test/CodeGen/builtin_clrsb.c @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +int test__builtin_clrsb(int x) { +// CHECK-LABEL: test__builtin_clrsb +// CHECK: [[C:%.*]] = icmp slt i32 [[X:%.*]], 0 +// CHECK-NEXT: [[INV:%.*]] = xor i32 [[X]], -1 +// CHECK-NEXT: [[SEL:%.*]] = select i1 [[C]], i32 [[INV]], i32 [[X]] +// CHECK-NEXT: [[CTLZ:%.*]] = call i32 @llvm.ctlz.i32(i32 [[SEL]], i1 false) +// CHECK-NEXT: [[SUB:%.*]] = sub i32 [[CTLZ]], 1 + return __builtin_clrsb(x); +} + +int test__builtin_clrsbll(long long x) { +// CHECK-LABEL: test__builtin_clrsbll +// CHECK: [[C:%.*]] = icmp slt i64 [[X:%.*]], 0 +// CHECK-NEXT: [[INV:%.*]] = xor i64 [[X]], -1 +// CHECK-NEXT: [[SEL:%.*]] = select i1 [[C]], i64 [[INV]], i64 [[X]] +// CHECK-NEXT: [[CTLZ:%.*]] = call i64 @llvm.ctlz.i64(i64 [[SEL]], i1 false) +// CHECK-NEXT: [[SUB:%.*]] = sub i64 [[CTLZ]], 1 +// CHECK-NEXT: trunc i64 [[SUB]] to i32 + re
[PATCH] D50471: [Builtins] Add __bulitin_clrsb support to IntExprEvaluator::VisitBuiltinCallExpr
This revision was automatically updated to reflect the committed changes. Closed by commit rC339287: [Builtins] Add __builtin_clrsb support to IntExprEvaluator::VisitBuiltinCallExpr (authored by ctopper, committed by ). Herald added a subscriber: kristina. Changed prior to commit: https://reviews.llvm.org/D50471?vs=159777&id=159786#toc Repository: rC Clang https://reviews.llvm.org/D50471 Files: lib/AST/ExprConstant.cpp test/Sema/constant-builtins-2.c Index: test/Sema/constant-builtins-2.c === --- test/Sema/constant-builtins-2.c +++ test/Sema/constant-builtins-2.c @@ -132,7 +132,7 @@ char clz1[__builtin_clz(1) == BITSIZE(int) - 1 ? 1 : -1]; char clz2[__builtin_clz(7) == BITSIZE(int) - 3 ? 1 : -1]; char clz3[__builtin_clz(1 << (BITSIZE(int) - 1)) == 0 ? 1 : -1]; -int clz4 = __builtin_clz(0); // expected-error {{not a compile-time constant}} +//int clz4 = __builtin_clz(0); // expected-error {{not a compile-time constant}} char clz5[__builtin_clzl(0xFL) == BITSIZE(long) - 4 ? 1 : -1]; char clz6[__builtin_clzll(0xFFLL) == BITSIZE(long long) - 8 ? 1 : -1]; char clz7[__builtin_clzs(0x1) == BITSIZE(short) - 1 ? 1 : -1]; @@ -142,7 +142,7 @@ char ctz1[__builtin_ctz(1) == 0 ? 1 : -1]; char ctz2[__builtin_ctz(8) == 3 ? 1 : -1]; char ctz3[__builtin_ctz(1 << (BITSIZE(int) - 1)) == BITSIZE(int) - 1 ? 1 : -1]; -int ctz4 = __builtin_ctz(0); // expected-error {{not a compile-time constant}} +//int ctz4 = __builtin_ctz(0); // expected-error {{not a compile-time constant}} char ctz5[__builtin_ctzl(0x10L) == 4 ? 1 : -1]; char ctz6[__builtin_ctzll(0x100LL) == 8 ? 1 : -1]; char ctz7[__builtin_ctzs(1 << (BITSIZE(short) - 1)) == BITSIZE(short) - 1 ? 1 : -1]; @@ -176,6 +176,19 @@ char ffs5[__builtin_ffs(1U << (BITSIZE(int) - 1)) == BITSIZE(int) ? 1 : -1]; char ffs6[__builtin_ffsl(0x10L) == 5 ? 1 : -1]; char ffs7[__builtin_ffsll(0x100LL) == 9 ? 1 : -1]; + +char clrsb1[__builtin_clrsb(0) == BITSIZE(int) - 1 ? 1 : -1]; +char clrsb2[__builtin_clrsbl(0L) == BITSIZE(long) - 1 ? 1 : -1]; +char clrsb3[__builtin_clrsbll(0LL) == BITSIZE(long long) - 1 ? 1 : -1]; +char clrsb4[__builtin_clrsb(~0) == BITSIZE(int) - 1 ? 1 : -1]; +char clrsb5[__builtin_clrsbl(~0L) == BITSIZE(long) - 1 ? 1 : -1]; +char clrsb6[__builtin_clrsbll(~0LL) == BITSIZE(long long) - 1 ? 1 : -1]; +char clrsb7[__builtin_clrsb(1) == BITSIZE(int) - 2 ? 1 : -1]; +char clrsb8[__builtin_clrsb(~1) == BITSIZE(int) - 2 ? 1 : -1]; +char clrsb9[__builtin_clrsb(1 << (BITSIZE(int) - 1)) == 0 ? 1 : -1]; +char clrsb10[__builtin_clrsb(~(1 << (BITSIZE(int) - 1))) == 0 ? 1 : -1]; +char clrsb11[__builtin_clrsb(0xf) == BITSIZE(int) - 5 ? 1 : -1]; +char clrsb11[__builtin_clrsb(~0x1f) == BITSIZE(int) - 6 ? 1 : -1]; #undef BITSIZE // GCC misc stuff Index: lib/AST/ExprConstant.cpp === --- lib/AST/ExprConstant.cpp +++ lib/AST/ExprConstant.cpp @@ -8117,9 +8117,15 @@ case Builtin::BI__builtin_classify_type: return Success((int)EvaluateBuiltinClassifyType(E, Info.getLangOpts()), E); - // FIXME: BI__builtin_clrsb - // FIXME: BI__builtin_clrsbl - // FIXME: BI__builtin_clrsbll + case Builtin::BI__builtin_clrsb: + case Builtin::BI__builtin_clrsbl: + case Builtin::BI__builtin_clrsbll: { +APSInt Val; +if (!EvaluateInteger(E->getArg(0), Val, Info)) + return false; + +return Success(Val.getBitWidth() - Val.getMinSignedBits(), E); + } case Builtin::BI__builtin_clz: case Builtin::BI__builtin_clzl: Index: test/Sema/constant-builtins-2.c === --- test/Sema/constant-builtins-2.c +++ test/Sema/constant-builtins-2.c @@ -132,7 +132,7 @@ char clz1[__builtin_clz(1) == BITSIZE(int) - 1 ? 1 : -1]; char clz2[__builtin_clz(7) == BITSIZE(int) - 3 ? 1 : -1]; char clz3[__builtin_clz(1 << (BITSIZE(int) - 1)) == 0 ? 1 : -1]; -int clz4 = __builtin_clz(0); // expected-error {{not a compile-time constant}} +//int clz4 = __builtin_clz(0); // expected-error {{not a compile-time constant}} char clz5[__builtin_clzl(0xFL) == BITSIZE(long) - 4 ? 1 : -1]; char clz6[__builtin_clzll(0xFFLL) == BITSIZE(long long) - 8 ? 1 : -1]; char clz7[__builtin_clzs(0x1) == BITSIZE(short) - 1 ? 1 : -1]; @@ -142,7 +142,7 @@ char ctz1[__builtin_ctz(1) == 0 ? 1 : -1]; char ctz2[__builtin_ctz(8) == 3 ? 1 : -1]; char ctz3[__builtin_ctz(1 << (BITSIZE(int) - 1)) == BITSIZE(int) - 1 ? 1 : -1]; -int ctz4 = __builtin_ctz(0); // expected-error {{not a compile-time constant}} +//int ctz4 = __builtin_ctz(0); // expected-error {{not a compile-time constant}} char ctz5[__builtin_ctzl(0x10L) == 4 ? 1 : -1]; char ctz6[__builtin_ctzll(0x100LL) == 8 ? 1 : -1]; char ctz7[__builtin_ctzs(1 << (BITSIZE(short) - 1)) == BITSIZE(short) - 1 ? 1 : -1]; @@ -176,6 +176,19 @@ char ffs5[__builtin_ffs(1U << (BITSIZE(int) - 1)) == BITSIZE(int) ? 1 : -1]; char ffs6[__builtin_ffsl(0x10L) == 5 ? 1 : -1]; char
[PATCH] D50418: [Sema] Support for P0961R1: Relaxing the structured bindings customization point finding rules
This revision was automatically updated to reflect the committed changes. Closed by commit rL339375: [Sema] P0961R1: Relaxing the structured bindings customization point finding… (authored by epilk, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D50418?vs=159629&id=159989#toc Repository: rL LLVM https://reviews.llvm.org/D50418 Files: cfe/trunk/lib/Sema/SemaDeclCXX.cpp cfe/trunk/test/CXX/dcl.decl/dcl.decomp/p3.cpp cfe/trunk/www/cxx_status.html Index: cfe/trunk/www/cxx_status.html === --- cfe/trunk/www/cxx_status.html +++ cfe/trunk/www/cxx_status.html @@ -755,7 +755,7 @@ http://wg21.link/p0961r1";>P0961R1 (DR) -No +SVN Index: cfe/trunk/test/CXX/dcl.decl/dcl.decomp/p3.cpp === --- cfe/trunk/test/CXX/dcl.decl/dcl.decomp/p3.cpp +++ cfe/trunk/test/CXX/dcl.decl/dcl.decomp/p3.cpp @@ -36,7 +36,7 @@ auto [a0, a1, a2] = A(); // expected-error {{undeclared identifier 'get'}} expected-note {{in implicit initialization of binding declaration 'a0'}} } -template float &get(A); +template float &get(A); // expected-note 2 {{no known conversion}} void no_tuple_element_1() { auto [a0, a1, a2] = A(); // expected-error-re {{'std::tuple_element<0U{{L*}}, A>::type' does not name a type}} expected-note {{in implicit}} @@ -57,7 +57,7 @@ template<> struct std::tuple_element<1, A> { typedef float &type; }; template<> struct std::tuple_element<2, A> { typedef const float &type; }; -template auto get(B) -> int (&)[N + 1]; +template auto get(B) -> int (&)[N + 1]; // expected-note 2 {{no known conversion}} template struct std::tuple_element { typedef int type[N +1 ]; }; template struct std::tuple_size : std::tuple_size {}; @@ -138,19 +138,25 @@ return c; } -struct D { template struct get {}; }; // expected-note {{declared here}} +struct D { + // FIXME: Emit a note here explaining why this was ignored. + template struct get {}; +}; template<> struct std::tuple_size { static const int value = 1; }; template<> struct std::tuple_element<0, D> { typedef D::get<0> type; }; void member_get_class_template() { - auto [d] = D(); // expected-error {{cannot refer to member 'get' in 'D' with '.'}} expected-note {{in implicit init}} + auto [d] = D(); // expected-error {{no matching function for call to 'get'}} expected-note {{in implicit init}} } -struct E { int get(); }; +struct E { + // FIXME: Emit a note here explaining why this was ignored. + int get(); +}; template<> struct std::tuple_size { static const int value = 1; }; template<> struct std::tuple_element<0, E> { typedef int type; }; void member_get_non_template() { // FIXME: This diagnostic is not very good. - auto [e] = E(); // expected-error {{no member named 'get'}} expected-note {{in implicit init}} + auto [e] = E(); // expected-error {{no matching function for call to 'get'}} expected-note {{in implicit init}} } namespace ADL { @@ -230,3 +236,62 @@ } static_assert(g() == 4); // expected-error {{constant}} expected-note {{in call to 'g()'}} } + +// P0961R1 +struct InvalidMemberGet { + int get(); + template int get(); + struct get {}; +}; +template <> struct std::tuple_size { static constexpr size_t value = 1; }; +template <> struct std::tuple_element<0, InvalidMemberGet> { typedef float type; }; +template float get(InvalidMemberGet) { return 0; } +int f() { + InvalidMemberGet img; + auto [x] = img; + typedef decltype(x) same_as_float; + typedef float same_as_float; +} + +struct ValidMemberGet { + int get(); + template int get() { return 0; } + template float get() { return 0; } +}; +template <> struct std::tuple_size { static constexpr size_t value = 1; }; +template <> struct std::tuple_element<0, ValidMemberGet> { typedef float type; }; +// Don't use this one; we should use the member get. +template int get(ValidMemberGet) { static_assert(N && false, ""); } +int f2() { + ValidMemberGet img; + auto [x] = img; + typedef decltype(x) same_as_float; + typedef float same_as_float; +} + +struct Base1 { + int get(); // expected-note{{member found by ambiguous name lookup}} +}; +struct Base2 { + template int get(); // expected-note{{member found by ambiguous name lookup}} +}; +struct Derived : Base1, Base2 {}; + +template <> struct std::tuple_size { static constexpr size_t value = 1; }; +template <> struct std::tuple_element<0, Derived> { typedef int type; }; + +auto [x] = Derived(); // expected-error{{member 'get' found in multiple base classes of different types}} + +struct Base { + template int get(); +}; +struct UsingGet : Base { + using Base::get; +}; + +template <> struct std::tuple_size { + static constexpr size_t value = 1; +}; +template <> struct std::tuple_element<0, UsingGet> { typedef int type; }; + +auto [y] = UsingGet(); Index: cfe/trun
[PATCH] D50532: Fix a wrong type bug in ParsedAttr::TypeTagForDatatypeData
This revision was automatically updated to reflect the committed changes. Closed by commit rC339423: Fix a wrong type bug in ParsedAttr::TypeTagForDatatypeData (authored by brunoricci, committed by ). Changed prior to commit: https://reviews.llvm.org/D50532?vs=159988&id=160086#toc Repository: rC Clang https://reviews.llvm.org/D50532 Files: include/clang/Sema/ParsedAttr.h Index: include/clang/Sema/ParsedAttr.h === --- include/clang/Sema/ParsedAttr.h +++ include/clang/Sema/ParsedAttr.h @@ -78,7 +78,7 @@ }; struct TypeTagForDatatypeData { - ParsedType *MatchingCType; + ParsedType MatchingCType; unsigned LayoutCompatible : 1; unsigned MustBeNull : 1; }; @@ -502,7 +502,7 @@ const ParsedType &getMatchingCType() const { assert(getKind() == AT_TypeTagForDatatype && "Not a type_tag_for_datatype attribute"); -return *getTypeTagForDatatypeDataSlot().MatchingCType; +return getTypeTagForDatatypeDataSlot().MatchingCType; } bool getLayoutCompatible() const { Index: include/clang/Sema/ParsedAttr.h === --- include/clang/Sema/ParsedAttr.h +++ include/clang/Sema/ParsedAttr.h @@ -78,7 +78,7 @@ }; struct TypeTagForDatatypeData { - ParsedType *MatchingCType; + ParsedType MatchingCType; unsigned LayoutCompatible : 1; unsigned MustBeNull : 1; }; @@ -502,7 +502,7 @@ const ParsedType &getMatchingCType() const { assert(getKind() == AT_TypeTagForDatatype && "Not a type_tag_for_datatype attribute"); -return *getTypeTagForDatatypeDataSlot().MatchingCType; +return getTypeTagForDatatypeDataSlot().MatchingCType; } bool getLayoutCompatible() const { ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D36892: [clang-tidy] check_clang_tidy.py: support CHECK-NOTES prefix
This revision was automatically updated to reflect the committed changes. Closed by commit rL339437: [clang-tidy] check_clang_tidy.py: support CHECK-NOTES prefix (authored by lebedevri, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D36892?vs=160107&id=160108#toc Repository: rL LLVM https://reviews.llvm.org/D36892 Files: clang-tools-extra/trunk/docs/clang-tidy/index.rst clang-tools-extra/trunk/test/clang-tidy/check_clang_tidy.py clang-tools-extra/trunk/test/clang-tidy/hicpp-exception-baseclass.cpp Index: clang-tools-extra/trunk/docs/clang-tidy/index.rst === --- clang-tools-extra/trunk/docs/clang-tidy/index.rst +++ clang-tools-extra/trunk/docs/clang-tidy/index.rst @@ -650,7 +650,8 @@ An additional check enabled by ``check_clang_tidy.py`` ensures that if `CHECK-MESSAGES:` is used in a file then every warning or error -must have an associated CHECK in that file. +must have an associated CHECK in that file. Or, you can use ``CHECK-NOTES:`` +instead, if you want to **also** ensure that all the notes are checked. To use the ``check_clang_tidy.py`` script, put a .cpp file with the appropriate ``RUN`` line in the ``test/clang-tidy`` directory. Use Index: clang-tools-extra/trunk/test/clang-tidy/check_clang_tidy.py === --- clang-tools-extra/trunk/test/clang-tidy/check_clang_tidy.py +++ clang-tools-extra/trunk/test/clang-tidy/check_clang_tidy.py @@ -78,6 +78,7 @@ file_check_suffix = ('-' + args.check_suffix) if args.check_suffix else '' check_fixes_prefix = 'CHECK-FIXES' + file_check_suffix check_messages_prefix = 'CHECK-MESSAGES' + file_check_suffix + check_notes_prefix = 'CHECK-NOTES' + file_check_suffix # Tests should not rely on STL being available, and instead provide mock # implementations of relevant APIs. @@ -91,9 +92,11 @@ has_check_fixes = check_fixes_prefix in input_text has_check_messages = check_messages_prefix in input_text + has_check_notes = check_notes_prefix in input_text - if not has_check_fixes and not has_check_messages: -sys.exit('Neither %s nor %s found in the input' % (check_fixes_prefix, check_messages_prefix) ) + if not has_check_fixes and not has_check_messages and not has_check_notes: +sys.exit('%s, %s or %s not found in the input' % (check_fixes_prefix, + check_messages_prefix, check_notes_prefix) ) # Remove the contents of the CHECK lines to avoid CHECKs matching on # themselves. We need to keep the comments to preserve line numbers while @@ -156,5 +159,18 @@ print('FileCheck failed:\n' + e.output.decode()) raise + if has_check_notes: +notes_file = temp_file_name + '.notes' +write_file(notes_file, clang_tidy_output) +try: + subprocess.check_output( + ['FileCheck', '-input-file=' + notes_file, input_file_name, + '-check-prefix=' + check_notes_prefix, + '-implicit-check-not={{note|warning|error}}:'], + stderr=subprocess.STDOUT) +except subprocess.CalledProcessError as e: + print('FileCheck failed:\n' + e.output.decode()) + raise + if __name__ == '__main__': main() Index: clang-tools-extra/trunk/test/clang-tidy/hicpp-exception-baseclass.cpp === --- clang-tools-extra/trunk/test/clang-tidy/hicpp-exception-baseclass.cpp +++ clang-tools-extra/trunk/test/clang-tidy/hicpp-exception-baseclass.cpp @@ -20,28 +20,28 @@ void problematic() { try { throw int(42); -// CHECK-MESSAGES: [[@LINE-1]]:11: warning: throwing an exception whose type 'int' is not derived from 'std::exception' +// CHECK-NOTES: [[@LINE-1]]:11: warning: throwing an exception whose type 'int' is not derived from 'std::exception' } catch (int e) { } throw int(42); - // CHECK-MESSAGES: [[@LINE-1]]:9: warning: throwing an exception whose type 'int' is not derived from 'std::exception' + // CHECK-NOTES: [[@LINE-1]]:9: warning: throwing an exception whose type 'int' is not derived from 'std::exception' try { throw 12; -// CHECK-MESSAGES: [[@LINE-1]]:11: warning: throwing an exception whose type 'int' is not derived from 'std::exception' +// CHECK-NOTES: [[@LINE-1]]:11: warning: throwing an exception whose type 'int' is not derived from 'std::exception' } catch (...) { throw; // Ok, even if the type is not known, conforming code can never rethrow a non-std::exception object. } try { throw non_derived_exception(); -// CHECK-MESSAGES: [[@LINE-1]]:11: warning: throwing an exception whose type 'non_derived_exception' is not derived from 'std::exception' -// CHECK-MESSAGES: 9:1: note: type defined here +// CHECK-NOTES: [[@LINE-1]]:11: warning: throwing an exception whose type 'non_derived_exception' is not derived from 'std::exception' +// CHECK-
[PATCH] D49570: [analyzer] Improve warning messages and notes of InnerPointerChecker
This revision was automatically updated to reflect the committed changes. Closed by commit rL339489: [analyzer] InnerPointerChecker: improve warning messages and notes. (authored by rkovacs, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D49570?vs=160193&id=160213#toc Repository: rL LLVM https://reviews.llvm.org/D49570 Files: cfe/trunk/lib/StaticAnalyzer/Checkers/AllocationState.h cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp cfe/trunk/test/Analysis/inner-pointer.cpp Index: cfe/trunk/lib/StaticAnalyzer/Checkers/AllocationState.h === --- cfe/trunk/lib/StaticAnalyzer/Checkers/AllocationState.h +++ cfe/trunk/lib/StaticAnalyzer/Checkers/AllocationState.h @@ -26,6 +26,11 @@ /// AF_InnerBuffer symbols. std::unique_ptr getInnerPointerBRVisitor(SymbolRef Sym); +/// 'Sym' represents a pointer to the inner buffer of a container object. +/// This function looks up the memory region of that object in +/// DanglingInternalBufferChecker's program state map. +const MemRegion *getContainerObjRegion(ProgramStateRef State, SymbolRef Sym); + } // end namespace allocation_state } // end namespace ento Index: cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp === --- cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp +++ cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp @@ -279,6 +279,28 @@ C.addTransition(State); } +namespace clang { +namespace ento { +namespace allocation_state { + +std::unique_ptr getInnerPointerBRVisitor(SymbolRef Sym) { + return llvm::make_unique(Sym); +} + +const MemRegion *getContainerObjRegion(ProgramStateRef State, SymbolRef Sym) { + RawPtrMapTy Map = State->get(); + for (const auto Entry : Map) { +if (Entry.second.contains(Sym)) { + return Entry.first; +} + } + return nullptr; +} + +} // end namespace allocation_state +} // end namespace ento +} // end namespace clang + std::shared_ptr InnerPointerChecker::InnerPointerBRVisitor::VisitNode(const ExplodedNode *N, const ExplodedNode *PrevN, @@ -292,27 +314,21 @@ if (!S) return nullptr; + const MemRegion *ObjRegion = + allocation_state::getContainerObjRegion(N->getState(), PtrToBuf); + const auto *TypedRegion = cast(ObjRegion); + QualType ObjTy = TypedRegion->getValueType(); + SmallString<256> Buf; llvm::raw_svector_ostream OS(Buf); - OS << "Dangling inner pointer obtained here"; + OS << "Pointer to inner buffer of '" << ObjTy.getAsString() + << "' obtained here"; PathDiagnosticLocation Pos(S, BRC.getSourceManager(), N->getLocationContext()); return std::make_shared(Pos, OS.str(), true, nullptr); } -namespace clang { -namespace ento { -namespace allocation_state { - -std::unique_ptr getInnerPointerBRVisitor(SymbolRef Sym) { - return llvm::make_unique(Sym); -} - -} // end namespace allocation_state -} // end namespace ento -} // end namespace clang - void ento::registerInnerPointerChecker(CheckerManager &Mgr) { registerInnerPointerCheckerAux(Mgr); Mgr.registerChecker(); Index: cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp === --- cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -1996,15 +1996,20 @@ BT_UseFree[*CheckKind].reset(new BugType( CheckNames[*CheckKind], "Use-after-free", categories::MemoryError)); +AllocationFamily AF = +C.getState()->get(Sym)->getAllocationFamily(); + auto R = llvm::make_unique(*BT_UseFree[*CheckKind], - "Use of memory after it is freed", N); +AF == AF_InnerBuffer + ? "Inner pointer of container used after re/deallocation" + : "Use of memory after it is freed", +N); R->markInteresting(Sym); R->addRange(Range); R->addVisitor(llvm::make_unique(Sym)); -const RefState *RS = C.getState()->get(Sym); -if (RS->getAllocationFamily() == AF_InnerBuffer) +if (AF == AF_InnerBuffer) R->addVisitor(allocation_state::getInnerPointerBRVisitor(Sym)); C.emitReport(std::move(R)); @@ -2944,13 +2949,22 @@ case AF_CXXNewArray: case AF_IfNameIndex: Msg = "Memory is released"; + StackHint = new StackHintGeneratorForSymbol(Sym, + "Returning; memory was released"); break; case AF_InnerBuffer: { - OS << "Inner pointer invalidated by call to "; + const MemRegion *ObjRegion = + allocation_state::getConta
[PATCH] D50630: [AST] Update/correct the static_asserts for the bit-fields in Type
This revision was automatically updated to reflect the committed changes. Closed by commit rC339582: [AST] Update/correct the static_asserts for the bit-fields in Type (authored by brunoricci, committed by ). Repository: rC Clang https://reviews.llvm.org/D50630 Files: include/clang/AST/Type.h Index: include/clang/AST/Type.h === --- include/clang/AST/Type.h +++ include/clang/AST/Type.h @@ -1539,8 +1539,6 @@ unsigned IsKindOf : 1; }; - static_assert(NumTypeBits + 7 + 6 + 1 <= 32, "Does not fit in an unsigned"); - class ReferenceTypeBitfields { friend class ReferenceType; @@ -1619,6 +1617,27 @@ ReferenceTypeBitfields ReferenceTypeBits; TypeWithKeywordBitfields TypeWithKeywordBits; VectorTypeBitfields VectorTypeBits; + +static_assert(sizeof(TypeBitfields) <= 8, + "TypeBitfields is larger than 8 bytes!"); +static_assert(sizeof(ArrayTypeBitfields) <= 8, + "ArrayTypeBitfields is larger than 8 bytes!"); +static_assert(sizeof(AttributedTypeBitfields) <= 8, + "AttributedTypeBitfields is larger than 8 bytes!"); +static_assert(sizeof(AutoTypeBitfields) <= 8, + "AutoTypeBitfields is larger than 8 bytes!"); +static_assert(sizeof(BuiltinTypeBitfields) <= 8, + "BuiltinTypeBitfields is larger than 8 bytes!"); +static_assert(sizeof(FunctionTypeBitfields) <= 8, + "FunctionTypeBitfields is larger than 8 bytes!"); +static_assert(sizeof(ObjCObjectTypeBitfields) <= 8, + "ObjCObjectTypeBitfields is larger than 8 bytes!"); +static_assert(sizeof(ReferenceTypeBitfields) <= 8, + "ReferenceTypeBitfields is larger than 8 bytes!"); +static_assert(sizeof(TypeWithKeywordBitfields) <= 8, + "TypeWithKeywordBitfields is larger than 8 bytes!"); +static_assert(sizeof(VectorTypeBitfields) <= 8, + "VectorTypeBitfields is larger than 8 bytes!"); }; private: Index: include/clang/AST/Type.h === --- include/clang/AST/Type.h +++ include/clang/AST/Type.h @@ -1539,8 +1539,6 @@ unsigned IsKindOf : 1; }; - static_assert(NumTypeBits + 7 + 6 + 1 <= 32, "Does not fit in an unsigned"); - class ReferenceTypeBitfields { friend class ReferenceType; @@ -1619,6 +1617,27 @@ ReferenceTypeBitfields ReferenceTypeBits; TypeWithKeywordBitfields TypeWithKeywordBits; VectorTypeBitfields VectorTypeBits; + +static_assert(sizeof(TypeBitfields) <= 8, + "TypeBitfields is larger than 8 bytes!"); +static_assert(sizeof(ArrayTypeBitfields) <= 8, + "ArrayTypeBitfields is larger than 8 bytes!"); +static_assert(sizeof(AttributedTypeBitfields) <= 8, + "AttributedTypeBitfields is larger than 8 bytes!"); +static_assert(sizeof(AutoTypeBitfields) <= 8, + "AutoTypeBitfields is larger than 8 bytes!"); +static_assert(sizeof(BuiltinTypeBitfields) <= 8, + "BuiltinTypeBitfields is larger than 8 bytes!"); +static_assert(sizeof(FunctionTypeBitfields) <= 8, + "FunctionTypeBitfields is larger than 8 bytes!"); +static_assert(sizeof(ObjCObjectTypeBitfields) <= 8, + "ObjCObjectTypeBitfields is larger than 8 bytes!"); +static_assert(sizeof(ReferenceTypeBitfields) <= 8, + "ReferenceTypeBitfields is larger than 8 bytes!"); +static_assert(sizeof(TypeWithKeywordBitfields) <= 8, + "TypeWithKeywordBitfields is larger than 8 bytes!"); +static_assert(sizeof(VectorTypeBitfields) <= 8, + "VectorTypeBitfields is larger than 8 bytes!"); }; private: ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D50645: [clangd] Show non-instantiated decls in signatureHelp
This revision was automatically updated to reflect the committed changes. Closed by commit rL339665: [clangd] Show non-instantiated decls in signatureHelp (authored by ibiryukov, committed by ). Herald added a subscriber: llvm-commits. Repository: rL LLVM https://reviews.llvm.org/D50645 Files: clang-tools-extra/trunk/clangd/CodeComplete.cpp clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp Index: clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp === --- clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp +++ clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp @@ -1537,6 +1537,59 @@ EXPECT_EQ(0, Results.activeParameter); } +TEST(SignatureHelpTest, InstantiatedSignatures) { + EXPECT_THAT(signatures(R"cpp( +template +void foo(T, T, T); + +int main() { + foo(^); +} + )cpp") + .signatures, + ElementsAre(Sig("foo(T, T, T) -> void", {"T", "T", "T"}))); + + EXPECT_THAT(signatures(R"cpp( +template +void foo(T, T, T); + +int main() { + foo(10, ^); +})cpp") + .signatures, + ElementsAre(Sig("foo(T, T, T) -> void", {"T", "T", "T"}))); + + EXPECT_THAT(signatures(R"cpp( +template +void foo(T...); + +int main() { + foo(^); +} + )cpp") + .signatures, + ElementsAre(Sig("foo(T...) -> void", {"T..."}))); + + // It is debatable whether we should substitute the outer template parameter + // ('T') in that case. Currently we don't substitute it in signature help, but + // do substitute in code complete. + // FIXME: make code complete and signature help consistent, figure out which + // way is better. + EXPECT_THAT(signatures(R"cpp( +template +struct X { + template + void foo(T, U); +}; + +int main() { + X().foo(^) +} + )cpp") + .signatures, + ElementsAre(Sig("foo(T, U) -> void", {"T", "U"}))); +} + } // namespace } // namespace clangd } // namespace clang Index: clang-tools-extra/trunk/clangd/CodeComplete.cpp === --- clang-tools-extra/trunk/clangd/CodeComplete.cpp +++ clang-tools-extra/trunk/clangd/CodeComplete.cpp @@ -714,7 +714,15 @@ "too many arguments"); SigHelp.activeParameter = static_cast(CurrentArg); for (unsigned I = 0; I < NumCandidates; ++I) { - const auto &Candidate = Candidates[I]; + OverloadCandidate Candidate = Candidates[I]; + // We want to avoid showing instantiated signatures, because they may be + // long in some cases (e.g. when 'T' is substituted with 'std::string', we + // would get 'std::basic_string'). + if (auto *Func = Candidate.getFunction()) { +if (auto *Pattern = Func->getTemplateInstantiationPattern()) + Candidate = OverloadCandidate(Pattern); + } + const auto *CCS = Candidate.CreateSignatureString( CurrentArg, S, *Allocator, CCTUInfo, true); assert(CCS && "Expected the CodeCompletionString to be non-null"); Index: clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp === --- clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp +++ clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp @@ -1537,6 +1537,59 @@ EXPECT_EQ(0, Results.activeParameter); } +TEST(SignatureHelpTest, InstantiatedSignatures) { + EXPECT_THAT(signatures(R"cpp( +template +void foo(T, T, T); + +int main() { + foo(^); +} + )cpp") + .signatures, + ElementsAre(Sig("foo(T, T, T) -> void", {"T", "T", "T"}))); + + EXPECT_THAT(signatures(R"cpp( +template +void foo(T, T, T); + +int main() { + foo(10, ^); +})cpp") + .signatures, + ElementsAre(Sig("foo(T, T, T) -> void", {"T", "T", "T"}))); + + EXPECT_THAT(signatures(R"cpp( +template +void foo(T...); + +int main() { + foo(^); +} + )cpp") + .signatures, + ElementsAre(Sig("foo(T...) -> void", {"T..."}))); + + // It is debatable whether we should substitute the outer template parameter + // ('T') in that case. Currently we don't substitute it in signature help, but + // do substitute in code complete. + // FIXME: make code complete and signature help consistent, figure out which + // way is better. + EXPECT_THAT(signatures(R"cpp( +template +struct X { + template + void foo(T, U); +}; + +int main() { + X().foo(^) +} + )cpp") + .signatures, + ElementsAre(Sig("foo(T, U) -> void", {"T", "U"}))); +} + } // namespace } // namespace clangd } // namespace clang Index: clang-tools-extra/trunk/clangd/CodeComplete.cpp ===
[PATCH] D50678: [InlineAsm] Update the min-legal-vector-width function attribute based on inputs and outputs to inline assembly
This revision was automatically updated to reflect the committed changes. Closed by commit rC339721: [InlineAsm] Update the min-legal-vector-width function attribute based on… (authored by ctopper, committed by ). Repository: rC Clang https://reviews.llvm.org/D50678 Files: lib/CodeGen/CGStmt.cpp test/CodeGen/x86-inline-asm-min-vector-width.c Index: test/CodeGen/x86-inline-asm-min-vector-width.c === --- test/CodeGen/x86-inline-asm-min-vector-width.c +++ test/CodeGen/x86-inline-asm-min-vector-width.c @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -emit-llvm -target-feature +avx512f -o - | FileCheck %s + +typedef long long __m128i __attribute__ ((vector_size (16))); +typedef long long __m256i __attribute__ ((vector_size (32))); +typedef long long __m512i __attribute__ ((vector_size (64))); + +// CHECK: define <2 x i64> @testXMMout(<2 x i64>* %p) #0 +__m128i testXMMout(__m128i *p) { + __m128i xmm0; + __asm__("vmovdqu %1, %0" :"=v"(xmm0) : "m"(*(__m128i*)p)); + return xmm0; +} + +// CHECK: define <4 x i64> @testYMMout(<4 x i64>* %p) #1 +__m256i testYMMout(__m256i *p) { + __m256i ymm0; + __asm__("vmovdqu %1, %0" :"=v"(ymm0) : "m"(*(__m256i*)p)); + return ymm0; +} + +// CHECK: define <8 x i64> @testZMMout(<8 x i64>* %p) #2 +__m512i testZMMout(__m512i *p) { + __m512i zmm0; + __asm__("vmovdqu64 %1, %0" :"=v"(zmm0) : "m"(*(__m512i*)p)); + return zmm0; +} + +// CHECK: define void @testXMMin(<2 x i64> %xmm0, <2 x i64>* %p) #0 +void testXMMin(__m128i xmm0, __m128i *p) { + __asm__("vmovdqu %0, %1" : : "v"(xmm0), "m"(*(__m128i*)p)); +} + +// CHECK: define void @testYMMin(<4 x i64> %ymm0, <4 x i64>* %p) #1 +void testYMMin(__m256i ymm0, __m256i *p) { + __asm__("vmovdqu %0, %1" : : "v"(ymm0), "m"(*(__m256i*)p)); +} + +// CHECK: define void @testZMMin(<8 x i64> %zmm0, <8 x i64>* %p) #2 +void testZMMin(__m512i zmm0, __m512i *p) { + __asm__("vmovdqu64 %0, %1" : : "v"(zmm0), "m"(*(__m512i*)p)); +} + +// CHECK: attributes #0 = {{.*}}"min-legal-vector-width"="128" +// CHECK: attributes #1 = {{.*}}"min-legal-vector-width"="256" +// CHECK: attributes #2 = {{.*}}"min-legal-vector-width"="512" Index: lib/CodeGen/CGStmt.cpp === --- lib/CodeGen/CGStmt.cpp +++ lib/CodeGen/CGStmt.cpp @@ -1979,6 +1979,11 @@ diag::err_asm_invalid_type_in_input) << OutExpr->getType() << OutputConstraint; } + + // Update largest vector width for any vector types. + if (auto *VT = dyn_cast(ResultRegTypes.back())) +LargestVectorWidth = std::max(LargestVectorWidth, + VT->getPrimitiveSizeInBits()); } else { ArgTypes.push_back(Dest.getAddress().getType()); Args.push_back(Dest.getPointer()); @@ -2000,6 +2005,10 @@ Arg->getType())) Arg = Builder.CreateBitCast(Arg, AdjTy); + // Update largest vector width for any vector types. + if (auto *VT = dyn_cast(Arg->getType())) +LargestVectorWidth = std::max(LargestVectorWidth, + VT->getPrimitiveSizeInBits()); if (Info.allowsRegister()) InOutConstraints += llvm::utostr(i); else @@ -2080,6 +2089,11 @@ CGM.getDiags().Report(S.getAsmLoc(), diag::err_asm_invalid_type_in_input) << InputExpr->getType() << InputConstraint; +// Update largest vector width for any vector types. +if (auto *VT = dyn_cast(Arg->getType())) + LargestVectorWidth = std::max(LargestVectorWidth, +VT->getPrimitiveSizeInBits()); + ArgTypes.push_back(Arg->getType()); Args.push_back(Arg); Constraints += InputConstraint; Index: test/CodeGen/x86-inline-asm-min-vector-width.c === --- test/CodeGen/x86-inline-asm-min-vector-width.c +++ test/CodeGen/x86-inline-asm-min-vector-width.c @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -emit-llvm -target-feature +avx512f -o - | FileCheck %s + +typedef long long __m128i __attribute__ ((vector_size (16))); +typedef long long __m256i __attribute__ ((vector_size (32))); +typedef long long __m512i __attribute__ ((vector_size (64))); + +// CHECK: define <2 x i64> @testXMMout(<2 x i64>* %p) #0 +__m128i testXMMout(__m128i *p) { + __m128i xmm0; + __asm__("vmovdqu %1, %0" :"=v"(xmm0) : "m"(*(__m128i*)p)); + return xmm0; +} + +// CHECK: define <4 x i64> @testYMMout(<4 x i64>* %p) #1 +__m256i testYMMout(__m256i *p) { + __m256i ymm0; + __asm__("vmovdqu %1, %0" :"=v"(ymm0) : "m"(*(__m256i*)p)); + return ymm0; +} + +// CHECK: define <8 x i64> @testZMMout(<8 x i64>* %p) #2 +__m512i testZMMout(__m512i *p) { + __m512i zmm0; + __asm__("vmovdqu64 %1, %0" :"=v"(zmm0) : "m"(*(__m512i*)p)); + return zmm0; +} + +// CHECK: define void @
[PATCH] D50487: [CFG] [analyzer] Find argument constructors in CXXTemporaryObjectExprs.
This revision was automatically updated to reflect the committed changes. Closed by commit rL339727: [CFG] [analyzer] Find argument constructors in CXXTemporaryObjectExprs. (authored by dergachev, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D50487?vs=159844&id=160689#toc Repository: rL LLVM https://reviews.llvm.org/D50487 Files: cfe/trunk/lib/Analysis/CFG.cpp cfe/trunk/test/Analysis/cfg-rich-constructors.cpp Index: cfe/trunk/test/Analysis/cfg-rich-constructors.cpp === --- cfe/trunk/test/Analysis/cfg-rich-constructors.cpp +++ cfe/trunk/test/Analysis/cfg-rich-constructors.cpp @@ -820,6 +820,7 @@ class E { public: E(D d); + E(D d1, D d2); }; void useC(C c); @@ -939,6 +940,38 @@ void passArgumentIntoAnotherConstructor() { E e = E(D()); } + + +// CHECK: void passTwoArgumentsIntoAnotherConstructor() +// CXX11-ELIDE: 1: argument_constructors::D() (CXXConstructExpr, [B1.2], [B1.4], [B1.5], class argument_constructors::D) +// CXX11-NOELIDE: 1: argument_constructors::D() (CXXConstructExpr, [B1.2], [B1.4], class argument_constructors::D) +// CXX11-NEXT: 2: [B1.1] (BindTemporary) +// CXX11-NEXT: 3: [B1.2] (ImplicitCastExpr, NoOp, const class argument_constructors::D) +// CXX11-NEXT: 4: [B1.3] +// CXX11-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.6], [B1.13]+0, class argument_constructors::D) +// CXX11-NEXT: 6: [B1.5] (BindTemporary) +// CXX11-ELIDE-NEXT: 7: argument_constructors::D() (CXXConstructExpr, [B1.8], [B1.10], [B1.11], class argument_constructors::D) +// CXX11-NOELIDE-NEXT: 7: argument_constructors::D() (CXXConstructExpr, [B1.8], [B1.10], class argument_constructors::D) +// CXX11-NEXT: 8: [B1.7] (BindTemporary) +// CXX11-NEXT: 9: [B1.8] (ImplicitCastExpr, NoOp, const class argument_constructors::D) +// CXX11-NEXT:10: [B1.9] +// CXX11-NEXT:11: [B1.10] (CXXConstructExpr, [B1.12], [B1.13]+1, class argument_constructors::D) +// CXX11-NEXT:12: [B1.11] (BindTemporary) +// CXX11-NEXT:13: argument_constructors::E([B1.6], [B1.12]) (CXXConstructExpr, class argument_constructors::E) +// CXX11-NEXT:14: ~argument_constructors::D() (Temporary object destructor) +// CXX11-NEXT:15: ~argument_constructors::D() (Temporary object destructor) +// CXX11-NEXT:16: ~argument_constructors::D() (Temporary object destructor) +// CXX11-NEXT:17: ~argument_constructors::D() (Temporary object destructor) +// CXX17: 1: argument_constructors::D() (CXXConstructExpr, [B1.2], [B1.5]+0, class argument_constructors::D) +// CXX17-NEXT: 2: [B1.1] (BindTemporary) +// CXX17-NEXT: 3: argument_constructors::D() (CXXConstructExpr, [B1.4], [B1.5]+1, class argument_constructors::D) +// CXX17-NEXT: 4: [B1.3] (BindTemporary) +// CXX17-NEXT: 5: argument_constructors::E([B1.2], [B1.4]) (CXXConstructExpr, class argument_constructors::E) +// CXX17-NEXT: 6: ~argument_constructors::D() (Temporary object destructor) +// CXX17-NEXT: 7: ~argument_constructors::D() (Temporary object destructor) +void passTwoArgumentsIntoAnotherConstructor() { + E(D(), D()); +} } // end namespace argument_constructors namespace copy_elision_with_extra_arguments { Index: cfe/trunk/lib/Analysis/CFG.cpp === --- cfe/trunk/lib/Analysis/CFG.cpp +++ cfe/trunk/lib/Analysis/CFG.cpp @@ -4352,6 +4352,11 @@ CFGBlock *CFGBuilder::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *C, AddStmtChoice asc) { + // If the constructor takes objects as arguments by value, we need to properly + // construct these objects. Construction contexts we find here aren't for the + // constructor C, they're for its arguments only. + findConstructionContextsForArguments(C); + autoCreateBlock(); appendConstructor(Block, C); return VisitChildren(C); Index: cfe/trunk/test/Analysis/cfg-rich-constructors.cpp === --- cfe/trunk/test/Analysis/cfg-rich-constructors.cpp +++ cfe/trunk/test/Analysis/cfg-rich-constructors.cpp @@ -820,6 +820,7 @@ class E { public: E(D d); + E(D d1, D d2); }; void useC(C c); @@ -939,6 +940,38 @@ void passArgumentIntoAnotherConstructor() { E e = E(D()); } + + +// CHECK: void passTwoArgumentsIntoAnotherConstructor() +// CXX11-ELIDE: 1: argument_constructors::D() (CXXConstructExpr, [B1.2], [B1.4], [B1.5], class argument_constructors::D) +// CXX11-NOELIDE: 1: argument_constructors::D() (CXXConstructExpr, [B1.2], [B1.4], class argument_constructors::D) +// CXX11-NEXT: 2: [B1.1] (BindTemporary) +// CXX11-NEXT: 3: [B1.2] (ImplicitCastExpr, NoOp, const class argument_constructors::D) +// CXX11-NEXT: 4: [B1.3] +// CXX11-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.6], [B1.13]+0, class ar
[PATCH] D50487: [CFG] [analyzer] Find argument constructors in CXXTemporaryObjectExprs.
This revision was automatically updated to reflect the committed changes. Closed by commit rC339727: [CFG] [analyzer] Find argument constructors in CXXTemporaryObjectExprs. (authored by dergachev, committed by ). Herald added a subscriber: Szelethus. Repository: rC Clang https://reviews.llvm.org/D50487 Files: lib/Analysis/CFG.cpp test/Analysis/cfg-rich-constructors.cpp Index: test/Analysis/cfg-rich-constructors.cpp === --- test/Analysis/cfg-rich-constructors.cpp +++ test/Analysis/cfg-rich-constructors.cpp @@ -820,6 +820,7 @@ class E { public: E(D d); + E(D d1, D d2); }; void useC(C c); @@ -939,6 +940,38 @@ void passArgumentIntoAnotherConstructor() { E e = E(D()); } + + +// CHECK: void passTwoArgumentsIntoAnotherConstructor() +// CXX11-ELIDE: 1: argument_constructors::D() (CXXConstructExpr, [B1.2], [B1.4], [B1.5], class argument_constructors::D) +// CXX11-NOELIDE: 1: argument_constructors::D() (CXXConstructExpr, [B1.2], [B1.4], class argument_constructors::D) +// CXX11-NEXT: 2: [B1.1] (BindTemporary) +// CXX11-NEXT: 3: [B1.2] (ImplicitCastExpr, NoOp, const class argument_constructors::D) +// CXX11-NEXT: 4: [B1.3] +// CXX11-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.6], [B1.13]+0, class argument_constructors::D) +// CXX11-NEXT: 6: [B1.5] (BindTemporary) +// CXX11-ELIDE-NEXT: 7: argument_constructors::D() (CXXConstructExpr, [B1.8], [B1.10], [B1.11], class argument_constructors::D) +// CXX11-NOELIDE-NEXT: 7: argument_constructors::D() (CXXConstructExpr, [B1.8], [B1.10], class argument_constructors::D) +// CXX11-NEXT: 8: [B1.7] (BindTemporary) +// CXX11-NEXT: 9: [B1.8] (ImplicitCastExpr, NoOp, const class argument_constructors::D) +// CXX11-NEXT:10: [B1.9] +// CXX11-NEXT:11: [B1.10] (CXXConstructExpr, [B1.12], [B1.13]+1, class argument_constructors::D) +// CXX11-NEXT:12: [B1.11] (BindTemporary) +// CXX11-NEXT:13: argument_constructors::E([B1.6], [B1.12]) (CXXConstructExpr, class argument_constructors::E) +// CXX11-NEXT:14: ~argument_constructors::D() (Temporary object destructor) +// CXX11-NEXT:15: ~argument_constructors::D() (Temporary object destructor) +// CXX11-NEXT:16: ~argument_constructors::D() (Temporary object destructor) +// CXX11-NEXT:17: ~argument_constructors::D() (Temporary object destructor) +// CXX17: 1: argument_constructors::D() (CXXConstructExpr, [B1.2], [B1.5]+0, class argument_constructors::D) +// CXX17-NEXT: 2: [B1.1] (BindTemporary) +// CXX17-NEXT: 3: argument_constructors::D() (CXXConstructExpr, [B1.4], [B1.5]+1, class argument_constructors::D) +// CXX17-NEXT: 4: [B1.3] (BindTemporary) +// CXX17-NEXT: 5: argument_constructors::E([B1.2], [B1.4]) (CXXConstructExpr, class argument_constructors::E) +// CXX17-NEXT: 6: ~argument_constructors::D() (Temporary object destructor) +// CXX17-NEXT: 7: ~argument_constructors::D() (Temporary object destructor) +void passTwoArgumentsIntoAnotherConstructor() { + E(D(), D()); +} } // end namespace argument_constructors namespace copy_elision_with_extra_arguments { Index: lib/Analysis/CFG.cpp === --- lib/Analysis/CFG.cpp +++ lib/Analysis/CFG.cpp @@ -4352,6 +4352,11 @@ CFGBlock *CFGBuilder::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *C, AddStmtChoice asc) { + // If the constructor takes objects as arguments by value, we need to properly + // construct these objects. Construction contexts we find here aren't for the + // constructor C, they're for its arguments only. + findConstructionContextsForArguments(C); + autoCreateBlock(); appendConstructor(Block, C); return VisitChildren(C); Index: test/Analysis/cfg-rich-constructors.cpp === --- test/Analysis/cfg-rich-constructors.cpp +++ test/Analysis/cfg-rich-constructors.cpp @@ -820,6 +820,7 @@ class E { public: E(D d); + E(D d1, D d2); }; void useC(C c); @@ -939,6 +940,38 @@ void passArgumentIntoAnotherConstructor() { E e = E(D()); } + + +// CHECK: void passTwoArgumentsIntoAnotherConstructor() +// CXX11-ELIDE: 1: argument_constructors::D() (CXXConstructExpr, [B1.2], [B1.4], [B1.5], class argument_constructors::D) +// CXX11-NOELIDE: 1: argument_constructors::D() (CXXConstructExpr, [B1.2], [B1.4], class argument_constructors::D) +// CXX11-NEXT: 2: [B1.1] (BindTemporary) +// CXX11-NEXT: 3: [B1.2] (ImplicitCastExpr, NoOp, const class argument_constructors::D) +// CXX11-NEXT: 4: [B1.3] +// CXX11-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.6], [B1.13]+0, class argument_constructors::D) +// CXX11-NEXT: 6: [B1.5] (BindTemporary) +// CXX11-ELIDE-NEXT: 7: argument_constructors::D() (CXXConstructExpr, [B1.8], [B1.10], [B1.11], class argument_constructo
[PATCH] D50643: [AST] Pack the bits of TemplateSpecializationType into Type
This revision was automatically updated to reflect the committed changes. Closed by commit rL339787: [AST] Pack the bits of TemplateSpecializationType into Type (authored by brunoricci, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D50643?vs=160805&id=160828#toc Repository: rL LLVM https://reviews.llvm.org/D50643 Files: cfe/trunk/include/clang/AST/Type.h cfe/trunk/lib/AST/Type.cpp Index: cfe/trunk/lib/AST/Type.cpp === --- cfe/trunk/lib/AST/Type.cpp +++ cfe/trunk/lib/AST/Type.cpp @@ -3335,8 +3335,10 @@ Canon.isNull()? true : Canon->isDependentType(), Canon.isNull()? true : Canon->isInstantiationDependentType(), false, - T.containsUnexpandedParameterPack()), -Template(T), NumArgs(Args.size()), TypeAlias(!AliasedType.isNull()) { + T.containsUnexpandedParameterPack()), Template(T) { + TemplateSpecializationTypeBits.NumArgs = Args.size(); + TemplateSpecializationTypeBits.TypeAlias = !AliasedType.isNull(); + assert(!T.getAsDependentTemplateName() && "Use DependentTemplateSpecializationType for dependent template-name"); assert((T.getKind() == TemplateName::Template || @@ -3365,7 +3367,7 @@ } // Store the aliased type if this is a type alias template specialization. - if (TypeAlias) { + if (isTypeAlias()) { auto *Begin = reinterpret_cast(this + 1); *reinterpret_cast(Begin + getNumArgs()) = AliasedType; } Index: cfe/trunk/include/clang/AST/Type.h === --- cfe/trunk/include/clang/AST/Type.h +++ cfe/trunk/include/clang/AST/Type.h @@ -1606,6 +1606,24 @@ unsigned Keyword : 2; }; + class TemplateSpecializationTypeBitfields { +friend class TemplateSpecializationType; + +unsigned : NumTypeBits; + +/// Whether this template specialization type is a substituted type alias. +unsigned TypeAlias : 1; + +/// The number of template arguments named in this class template +/// specialization, which is expected to be able to hold at least 1024 +/// according to [implimits]. However, as this limit is somewhat easy to +/// hit with template metaprogramming we'd prefer to keep it as large +/// as possible. At the moment it has been left as a non-bitfield since +/// this type safely fits in 64 bits as an unsigned, so there is no reason +/// to introduce the performance impact of a bitfield. +unsigned NumArgs; + }; + union { TypeBitfields TypeBits; ArrayTypeBitfields ArrayTypeBits; @@ -1617,6 +1635,7 @@ ReferenceTypeBitfields ReferenceTypeBits; TypeWithKeywordBitfields TypeWithKeywordBits; VectorTypeBitfields VectorTypeBits; +TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits; static_assert(sizeof(TypeBitfields) <= 8, "TypeBitfields is larger than 8 bytes!"); @@ -1638,6 +1657,9 @@ "TypeWithKeywordBitfields is larger than 8 bytes!"); static_assert(sizeof(VectorTypeBitfields) <= 8, "VectorTypeBitfields is larger than 8 bytes!"); +static_assert(sizeof(TemplateSpecializationTypeBitfields) <= 8, + "TemplateSpecializationTypeBitfields is larger" + " than 8 bytes!"); }; private: @@ -4669,13 +4691,6 @@ /// replacement must, recursively, be one of these). TemplateName Template; - /// The number of template arguments named in this class template - /// specialization. - unsigned NumArgs : 31; - - /// Whether this template specialization type is a substituted type alias. - unsigned TypeAlias : 1; - TemplateSpecializationType(TemplateName T, ArrayRef Args, QualType Canon, @@ -4710,7 +4725,7 @@ /// typedef A type; // not a type alias /// }; /// \endcode - bool isTypeAlias() const { return TypeAlias; } + bool isTypeAlias() const { return TemplateSpecializationTypeBits.TypeAlias; } /// Get the aliased type, if this is a specialization of a type alias /// template. @@ -4733,14 +4748,16 @@ } /// Retrieve the number of template arguments. - unsigned getNumArgs() const { return NumArgs; } + unsigned getNumArgs() const { +return TemplateSpecializationTypeBits.NumArgs; + } /// Retrieve a specific template argument as a type. /// \pre \c isArgType(Arg) const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h ArrayRef template_arguments() const { -return {getArgs(), NumArgs}; +return {getArgs(), getNumArgs()}; } bool isSugared() const { ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D50711: [AST] Pack the unsigned of PackExpansionType into Type
This revision was automatically updated to reflect the committed changes. Closed by commit rL339789: [AST] Pack the unsigned of PackExpansionType into Type (authored by brunoricci, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D50711?vs=160804&id=160831#toc Repository: rL LLVM https://reviews.llvm.org/D50711 Files: cfe/trunk/include/clang/AST/Type.h Index: cfe/trunk/include/clang/AST/Type.h === --- cfe/trunk/include/clang/AST/Type.h +++ cfe/trunk/include/clang/AST/Type.h @@ -1624,6 +1624,25 @@ unsigned NumArgs; }; + class PackExpansionTypeBitfields { +friend class PackExpansionType; + +unsigned : NumTypeBits; + +/// The number of expansions that this pack expansion will +/// generate when substituted (+1), which is expected to be able to +/// hold at least 1024 according to [implimits]. However, as this limit +/// is somewhat easy to hit with template metaprogramming we'd prefer to +/// keep it as large as possible. At the moment it has been left as a +/// non-bitfield since this type safely fits in 64 bits as an unsigned, so +/// there is no reason to introduce the performance impact of a bitfield. +/// +/// This field will only have a non-zero value when some of the parameter +/// packs that occur within the pattern have been substituted but others +/// have not. +unsigned NumExpansions; + }; + union { TypeBitfields TypeBits; ArrayTypeBitfields ArrayTypeBits; @@ -1636,6 +1655,7 @@ TypeWithKeywordBitfields TypeWithKeywordBits; VectorTypeBitfields VectorTypeBits; TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits; +PackExpansionTypeBitfields PackExpansionTypeBits; static_assert(sizeof(TypeBitfields) <= 8, "TypeBitfields is larger than 8 bytes!"); @@ -1660,6 +1680,8 @@ static_assert(sizeof(TemplateSpecializationTypeBitfields) <= 8, "TemplateSpecializationTypeBitfields is larger" " than 8 bytes!"); +static_assert(sizeof(PackExpansionTypeBitfields) <= 8, + "PackExpansionTypeBitfields is larger than 8 bytes"); }; private: @@ -5189,22 +5211,16 @@ /// The pattern of the pack expansion. QualType Pattern; - /// The number of expansions that this pack expansion will - /// generate when substituted (+1), or indicates that - /// - /// This field will only have a non-zero value when some of the parameter - /// packs that occur within the pattern have been substituted but others have - /// not. - unsigned NumExpansions; - PackExpansionType(QualType Pattern, QualType Canon, Optional NumExpansions) : Type(PackExpansion, Canon, /*Dependent=*/Pattern->isDependentType(), /*InstantiationDependent=*/true, /*VariablyModified=*/Pattern->isVariablyModifiedType(), /*ContainsUnexpandedParameterPack=*/false), -Pattern(Pattern), -NumExpansions(NumExpansions ? *NumExpansions + 1 : 0) {} +Pattern(Pattern) { +PackExpansionTypeBits.NumExpansions = +NumExpansions ? *NumExpansions + 1 : 0; + } public: /// Retrieve the pattern of this pack expansion, which is the @@ -5215,9 +5231,8 @@ /// Retrieve the number of expansions that this pack expansion will /// generate, if known. Optional getNumExpansions() const { -if (NumExpansions) - return NumExpansions - 1; - +if (PackExpansionTypeBits.NumExpansions) + return PackExpansionTypeBits.NumExpansions - 1; return None; } Index: cfe/trunk/include/clang/AST/Type.h === --- cfe/trunk/include/clang/AST/Type.h +++ cfe/trunk/include/clang/AST/Type.h @@ -1624,6 +1624,25 @@ unsigned NumArgs; }; + class PackExpansionTypeBitfields { +friend class PackExpansionType; + +unsigned : NumTypeBits; + +/// The number of expansions that this pack expansion will +/// generate when substituted (+1), which is expected to be able to +/// hold at least 1024 according to [implimits]. However, as this limit +/// is somewhat easy to hit with template metaprogramming we'd prefer to +/// keep it as large as possible. At the moment it has been left as a +/// non-bitfield since this type safely fits in 64 bits as an unsigned, so +/// there is no reason to introduce the performance impact of a bitfield. +/// +/// This field will only have a non-zero value when some of the parameter +/// packs that occur within the pattern have been substituted but others +/// have not. +unsigned NumExpansions; + }; + union { TypeBitfields TypeBits; ArrayTypeBitfields ArrayTypeBits; @@ -1636,6 +1655,7 @@ TypeWithKeywordBitfields TypeWithKeywordBits; VectorTypeBitfields VectorTypeBits;
[PATCH] D50618: Refactor Darwin driver to refer to runtimes by component
This revision was automatically updated to reflect the committed changes. Closed by commit rC339807: Refactor Darwin driver to refer to runtimes by component (authored by cbieneman, committed by ). Changed prior to commit: https://reviews.llvm.org/D50618?vs=160279&id=160903#toc Repository: rC Clang https://reviews.llvm.org/D50618 Files: lib/Driver/ToolChains/Darwin.cpp lib/Driver/ToolChains/Darwin.h Index: lib/Driver/ToolChains/Darwin.h === --- lib/Driver/ToolChains/Darwin.h +++ lib/Driver/ToolChains/Darwin.h @@ -189,9 +189,9 @@ /// Add a runtime library to the list of items to link. void AddLinkRuntimeLib(const llvm::opt::ArgList &Args, - llvm::opt::ArgStringList &CmdArgs, - StringRef DarwinLibName, - RuntimeLinkOptions Opts = RuntimeLinkOptions()) const; + llvm::opt::ArgStringList &CmdArgs, StringRef Component, + RuntimeLinkOptions Opts = RuntimeLinkOptions(), + bool IsShared = false) const; /// Add any profiling runtime libraries that are needed. This is essentially a /// MachO specific version of addProfileRT in Tools.cpp. @@ -252,6 +252,8 @@ return llvm::ExceptionHandling::None; } + virtual StringRef getOSLibraryNameSuffix() const { return ""; } + /// } }; @@ -418,7 +420,7 @@ Action::OffloadKind DeviceOffloadKind) const override; StringRef getPlatformFamily() const; - StringRef getOSLibraryNameSuffix() const; + StringRef getOSLibraryNameSuffix() const override; public: static StringRef getSDKName(StringRef isysroot); Index: lib/Driver/ToolChains/Darwin.cpp === --- lib/Driver/ToolChains/Darwin.cpp +++ lib/Driver/ToolChains/Darwin.cpp @@ -908,8 +908,17 @@ } void MachO::AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs, - StringRef DarwinLibName, - RuntimeLinkOptions Opts) const { + StringRef Component, RuntimeLinkOptions Opts, + bool IsShared) const { + SmallString<64> DarwinLibName = StringRef("libclang_rt."); + // an Darwin the builtins compomnent is not in the library name + if (Component != "builtins") { +DarwinLibName += Component; +if (!(Opts & RLO_IsEmbedded)) + DarwinLibName += "_"; + } + DarwinLibName += getOSLibraryNameSuffix(); + DarwinLibName += IsShared ? "_dynamic.dylib" : ".a"; SmallString<128> Dir(getDriver().ResourceDir); llvm::sys::path::append( Dir, "lib", (Opts & RLO_IsEmbedded) ? "macho_embedded" : "darwin"); @@ -1013,10 +1022,8 @@ ArgStringList &CmdArgs) const { if (!needsProfileRT(Args)) return; - AddLinkRuntimeLib( - Args, CmdArgs, - (Twine("libclang_rt.profile_") + getOSLibraryNameSuffix() + ".a").str(), - RuntimeLinkOptions(RLO_AlwaysLink | RLO_FirstLink)); + AddLinkRuntimeLib(Args, CmdArgs, "profile", +RuntimeLinkOptions(RLO_AlwaysLink | RLO_FirstLink)); // If we have a symbol export directive and we're linking in the profile // runtime, automatically export symbols necessary to implement some of the @@ -1033,12 +1040,7 @@ StringRef Sanitizer, bool Shared) const { auto RLO = RuntimeLinkOptions(RLO_AlwaysLink | (Shared ? RLO_AddRPath : 0U)); - AddLinkRuntimeLib(Args, CmdArgs, -(Twine("libclang_rt.") + Sanitizer + "_" + - getOSLibraryNameSuffix() + - (Shared ? "_dynamic.dylib" : ".a")) -.str(), -RLO); + AddLinkRuntimeLib(Args, CmdArgs, Sanitizer, RLO, Shared); } ToolChain::RuntimeLibType DarwinClang::GetRuntimeLibType( @@ -1092,10 +1094,7 @@ AddCXXStdlibLibArgs(Args, CmdArgs); } if (Sanitize.needsStatsRt()) { -StringRef OS = isTargetMacOS() ? "osx" : "iossim"; -AddLinkRuntimeLib(Args, CmdArgs, - (Twine("libclang_rt.stats_client_") + OS + ".a").str(), - RLO_AlwaysLink); +AddLinkRuntimeLib(Args, CmdArgs, "stats_client", RLO_AlwaysLink); AddLinkSanitizerLibArgs(Args, CmdArgs, "stats"); } if (Sanitize.needsEsanRt()) @@ -1106,52 +1105,15 @@ CmdArgs.push_back("-lSystem"); // Select the dynamic runtime library and the target specific static library. - if (isTargetWatchOSBased()) { -// We currently always need a static runtime library for watchOS. -AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.watchos.a"); - } else if (isTargetTvOSBased()) { -// We currently always need a static runtime library for tvOS. -AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.tvos.a"); - } else if (isTargetIOSBased()) {
[PATCH] D50712: [AST] Pack the unsigned of DependentTemplateSpecializationType into Type
This revision was automatically updated to reflect the committed changes. Closed by commit rL339860: [AST] Pack the unsigned of DependentTemplateSpecializationType into Type (authored by brunoricci, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D50712?vs=160800&id=160989#toc Repository: rL LLVM https://reviews.llvm.org/D50712 Files: cfe/trunk/include/clang/AST/Type.h cfe/trunk/lib/AST/Type.cpp Index: cfe/trunk/include/clang/AST/Type.h === --- cfe/trunk/include/clang/AST/Type.h +++ cfe/trunk/include/clang/AST/Type.h @@ -1571,6 +1571,8 @@ unsigned Keyword : 8; }; + enum { NumTypeWithKeywordBits = 8 }; + class VectorTypeBitfields { friend class VectorType; friend class DependentVectorType; @@ -1624,6 +1626,22 @@ unsigned NumArgs; }; + class DependentTemplateSpecializationTypeBitfields { +friend class DependentTemplateSpecializationType; + +unsigned : NumTypeBits; +unsigned : NumTypeWithKeywordBits; + +/// The number of template arguments named in this class template +/// specialization, which is expected to be able to hold at least 1024 +/// according to [implimits]. However, as this limit is somewhat easy to +/// hit with template metaprogramming we'd prefer to keep it as large +/// as possible. At the moment it has been left as a non-bitfield since +/// this type safely fits in 64 bits as an unsigned, so there is no reason +/// to introduce the performance impact of a bitfield. +unsigned NumArgs; + }; + class PackExpansionTypeBitfields { friend class PackExpansionType; @@ -1655,6 +1673,8 @@ TypeWithKeywordBitfields TypeWithKeywordBits; VectorTypeBitfields VectorTypeBits; TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits; +DependentTemplateSpecializationTypeBitfields + DependentTemplateSpecializationTypeBits; PackExpansionTypeBitfields PackExpansionTypeBits; static_assert(sizeof(TypeBitfields) <= 8, @@ -1680,6 +1700,9 @@ static_assert(sizeof(TemplateSpecializationTypeBitfields) <= 8, "TemplateSpecializationTypeBitfields is larger" " than 8 bytes!"); +static_assert(sizeof(DependentTemplateSpecializationTypeBitfields) <= 8, + "DependentTemplateSpecializationTypeBitfields is larger" + " than 8 bytes!"); static_assert(sizeof(PackExpansionTypeBitfields) <= 8, "PackExpansionTypeBitfields is larger than 8 bytes"); }; @@ -5123,10 +5146,6 @@ /// The identifier of the template. const IdentifierInfo *Name; - /// The number of template arguments named in this class template - /// specialization. - unsigned NumArgs; - DependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, const IdentifierInfo *Name, @@ -5151,12 +5170,14 @@ } /// Retrieve the number of template arguments. - unsigned getNumArgs() const { return NumArgs; } + unsigned getNumArgs() const { +return DependentTemplateSpecializationTypeBits.NumArgs; + } const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h ArrayRef template_arguments() const { -return {getArgs(), NumArgs}; +return {getArgs(), getNumArgs()}; } using iterator = const TemplateArgument *; @@ -5168,7 +5189,7 @@ QualType desugar() const { return QualType(this, 0); } void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) { -Profile(ID, Context, getKeyword(), NNS, Name, {getArgs(), NumArgs}); +Profile(ID, Context, getKeyword(), NNS, Name, {getArgs(), getNumArgs()}); } static void Profile(llvm::FoldingSetNodeID &ID, Index: cfe/trunk/lib/AST/Type.cpp === --- cfe/trunk/lib/AST/Type.cpp +++ cfe/trunk/lib/AST/Type.cpp @@ -2604,7 +2604,8 @@ : TypeWithKeyword(Keyword, DependentTemplateSpecialization, Canon, true, true, /*VariablyModified=*/false, NNS && NNS->containsUnexpandedParameterPack()), -NNS(NNS), Name(Name), NumArgs(Args.size()) { +NNS(NNS), Name(Name) { + DependentTemplateSpecializationTypeBits.NumArgs = Args.size(); assert((!NNS || NNS->isDependent()) && "DependentTemplateSpecializatonType requires dependent qualifier"); TemplateArgument *ArgBuffer = getArgBuffer(); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D50713: [AST] Pack the unsigned of SubstTemplateTypeParmPackType into Type
This revision was automatically updated to reflect the committed changes. Closed by commit rL339861: [AST] Pack the unsigned of SubstTemplateTypeParmPackType into Type (authored by brunoricci, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D50713?vs=160795&id=160991#toc Repository: rL LLVM https://reviews.llvm.org/D50713 Files: cfe/trunk/include/clang/AST/Type.h cfe/trunk/lib/AST/Type.cpp Index: cfe/trunk/lib/AST/Type.cpp === --- cfe/trunk/lib/AST/Type.cpp +++ cfe/trunk/lib/AST/Type.cpp @@ -3285,11 +3285,12 @@ QualType Canon, const TemplateArgument &ArgPack) : Type(SubstTemplateTypeParmPack, Canon, true, true, false, true), - Replaced(Param), - Arguments(ArgPack.pack_begin()), NumArguments(ArgPack.pack_size()) {} + Replaced(Param), Arguments(ArgPack.pack_begin()) { + SubstTemplateTypeParmPackTypeBits.NumArgs = ArgPack.pack_size(); +} TemplateArgument SubstTemplateTypeParmPackType::getArgumentPack() const { - return TemplateArgument(llvm::makeArrayRef(Arguments, NumArguments)); + return TemplateArgument(llvm::makeArrayRef(Arguments, getNumArgs())); } void SubstTemplateTypeParmPackType::Profile(llvm::FoldingSetNodeID &ID) { Index: cfe/trunk/include/clang/AST/Type.h === --- cfe/trunk/include/clang/AST/Type.h +++ cfe/trunk/include/clang/AST/Type.h @@ -1608,6 +1608,21 @@ unsigned Keyword : 2; }; + class SubstTemplateTypeParmPackTypeBitfields { +friend class SubstTemplateTypeParmPackType; + +unsigned : NumTypeBits; + +/// The number of template arguments in \c Arguments, which is +/// expected to be able to hold at least 1024 according to [implimits]. +/// However as this limit is somewhat easy to hit with template +/// metaprogramming we'd prefer to keep it as large as possible. +/// At the moment it has been left as a non-bitfield since this type +/// safely fits in 64 bits as an unsigned, so there is no reason to +/// introduce the performance impact of a bitfield. +unsigned NumArgs; + }; + class TemplateSpecializationTypeBitfields { friend class TemplateSpecializationType; @@ -1672,6 +1687,7 @@ ReferenceTypeBitfields ReferenceTypeBits; TypeWithKeywordBitfields TypeWithKeywordBits; VectorTypeBitfields VectorTypeBits; +SubstTemplateTypeParmPackTypeBitfields SubstTemplateTypeParmPackTypeBits; TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits; DependentTemplateSpecializationTypeBitfields DependentTemplateSpecializationTypeBits; @@ -1697,6 +1713,9 @@ "TypeWithKeywordBitfields is larger than 8 bytes!"); static_assert(sizeof(VectorTypeBitfields) <= 8, "VectorTypeBitfields is larger than 8 bytes!"); +static_assert(sizeof(SubstTemplateTypeParmPackTypeBitfields) <= 8, + "SubstTemplateTypeParmPackTypeBitfields is larger" + " than 8 bytes!"); static_assert(sizeof(TemplateSpecializationTypeBitfields) <= 8, "TemplateSpecializationTypeBitfields is larger" " than 8 bytes!"); @@ -4551,9 +4570,6 @@ /// parameter pack is instantiated with. const TemplateArgument *Arguments; - /// The number of template arguments in \c Arguments. - unsigned NumArguments; - SubstTemplateTypeParmPackType(const TemplateTypeParmType *Param, QualType Canon, const TemplateArgument &ArgPack); @@ -4566,6 +4582,10 @@ return Replaced; } + unsigned getNumArgs() const { +return SubstTemplateTypeParmPackTypeBits.NumArgs; + } + bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } Index: cfe/trunk/lib/AST/Type.cpp === --- cfe/trunk/lib/AST/Type.cpp +++ cfe/trunk/lib/AST/Type.cpp @@ -3285,11 +3285,12 @@ QualType Canon, const TemplateArgument &ArgPack) : Type(SubstTemplateTypeParmPack, Canon, true, true, false, true), - Replaced(Param), - Arguments(ArgPack.pack_begin()), NumArguments(ArgPack.pack_size()) {} + Replaced(Param), Arguments(ArgPack.pack_begin()) { + SubstTemplateTypeParmPackTypeBits.NumArgs = ArgPack.pack_size(); +} TemplateArgument SubstTemplateTypeParmPackType::getArgumentPack() const { - return TemplateArgument(llvm::makeArrayRef(Arguments, NumArguments)); + return TemplateArgument(llvm::makeArrayRef(Arguments, getNumArgs())); } void SubstTemplateTypeParmPackType::Profile(llvm::FoldingSetNodeID &ID) { Index: cfe/trunk/include/clang/AST/Type.h === --- cfe/trunk/i
[PATCH] D50715: [AST] Store the OwnedTagDecl as a trailing object in ElaboratedType.
This revision was automatically updated to reflect the committed changes. Closed by commit rL339862: [AST] Store the OwnedTagDecl as a trailing object in ElaboratedType. (authored by brunoricci, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D50715?vs=160606&id=160995#toc Repository: rL LLVM https://reviews.llvm.org/D50715 Files: cfe/trunk/include/clang/AST/Type.h cfe/trunk/lib/AST/ASTContext.cpp Index: cfe/trunk/include/clang/AST/Type.h === --- cfe/trunk/include/clang/AST/Type.h +++ cfe/trunk/include/clang/AST/Type.h @@ -45,6 +45,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/PointerLikeTypeTraits.h" #include "llvm/Support/type_traits.h" +#include "llvm/Support/TrailingObjects.h" #include #include #include @@ -1573,6 +1574,16 @@ enum { NumTypeWithKeywordBits = 8 }; + class ElaboratedTypeBitfields { +friend class ElaboratedType; + +unsigned : NumTypeBits; +unsigned : NumTypeWithKeywordBits; + +/// Whether the ElaboratedType has a trailing OwnedTagDecl. +unsigned HasOwnedTagDecl : 1; + }; + class VectorTypeBitfields { friend class VectorType; friend class DependentVectorType; @@ -1686,6 +1697,7 @@ ObjCObjectTypeBitfields ObjCObjectTypeBits; ReferenceTypeBitfields ReferenceTypeBits; TypeWithKeywordBitfields TypeWithKeywordBits; +ElaboratedTypeBitfields ElaboratedTypeBits; VectorTypeBitfields VectorTypeBits; SubstTemplateTypeParmPackTypeBitfields SubstTemplateTypeParmPackTypeBits; TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits; @@ -1711,6 +1723,8 @@ "ReferenceTypeBitfields is larger than 8 bytes!"); static_assert(sizeof(TypeWithKeywordBitfields) <= 8, "TypeWithKeywordBitfields is larger than 8 bytes!"); +static_assert(sizeof(ElaboratedTypeBitfields) <= 8, + "ElaboratedTypeBitfields is larger than 8 bytes!"); static_assert(sizeof(VectorTypeBitfields) <= 8, "VectorTypeBitfields is larger than 8 bytes!"); static_assert(sizeof(SubstTemplateTypeParmPackTypeBitfields) <= 8, @@ -5028,35 +5042,42 @@ /// source code, including tag keywords and any nested-name-specifiers. /// The type itself is always "sugar", used to express what was written /// in the source code but containing no additional semantic information. -class ElaboratedType : public TypeWithKeyword, public llvm::FoldingSetNode { +class ElaboratedType final +: public TypeWithKeyword, + public llvm::FoldingSetNode, + private llvm::TrailingObjects { friend class ASTContext; // ASTContext creates these + friend TrailingObjects; /// The nested name specifier containing the qualifier. NestedNameSpecifier *NNS; /// The type that this qualified name refers to. QualType NamedType; - /// The (re)declaration of this tag type owned by this occurrence, or nullptr - /// if none. - TagDecl *OwnedTagDecl; + /// The (re)declaration of this tag type owned by this occurrence is stored + /// as a trailing object if there is one. Use getOwnedTagDecl to obtain + /// it, or obtain a null pointer if there is none. ElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, QualType NamedType, QualType CanonType, TagDecl *OwnedTagDecl) -: TypeWithKeyword(Keyword, Elaborated, CanonType, - NamedType->isDependentType(), - NamedType->isInstantiationDependentType(), - NamedType->isVariablyModifiedType(), - NamedType->containsUnexpandedParameterPack()), - NNS(NNS), NamedType(NamedType), OwnedTagDecl(OwnedTagDecl) { + : TypeWithKeyword(Keyword, Elaborated, CanonType, +NamedType->isDependentType(), +NamedType->isInstantiationDependentType(), +NamedType->isVariablyModifiedType(), +NamedType->containsUnexpandedParameterPack()), +NNS(NNS), NamedType(NamedType) { +ElaboratedTypeBits.HasOwnedTagDecl = false; +if (OwnedTagDecl) { + ElaboratedTypeBits.HasOwnedTagDecl = true; + *getTrailingObjects() = OwnedTagDecl; +} assert(!(Keyword == ETK_None && NNS == nullptr) && "ElaboratedType cannot have elaborated type keyword " "and name qualifier both null."); } public: - ~ElaboratedType(); - /// Retrieve the qualification on this type. NestedNameSpecifier *getQualifier() const { return NNS; } @@ -5070,11 +5091,14 @@ bool isSugared() const { return true; } /// Return the (re)declaration of this type owned by this occurrence of this - /// type, or nullptr if none. - TagDecl *getOwnedTagDecl() const { return OwnedTagDecl; } + /// type, or nullptr if there is none. + TagDecl *getOwnedTagDecl() const {
[PATCH] D50726: [clangd] Show function documentation in sigHelp
This revision was automatically updated to reflect the committed changes. Closed by commit rL340004: [clangd] Show function documentation in signature help (authored by ibiryukov, committed by ). Herald added a subscriber: llvm-commits. Repository: rL LLVM https://reviews.llvm.org/D50726 Files: clang-tools-extra/trunk/clangd/CodeComplete.cpp clang-tools-extra/trunk/clangd/CodeCompletionStrings.cpp clang-tools-extra/trunk/clangd/CodeCompletionStrings.h Index: clang-tools-extra/trunk/clangd/CodeCompletionStrings.cpp === --- clang-tools-extra/trunk/clangd/CodeCompletionStrings.cpp +++ clang-tools-extra/trunk/clangd/CodeCompletionStrings.cpp @@ -51,44 +51,26 @@ // get this declaration, so we don't show documentation in that case. if (Result.Kind != CodeCompletionResult::RK_Declaration) return ""; - auto *Decl = Result.getDeclaration(); - if (!Decl || llvm::isa(Decl)) { + return Result.getDeclaration() ? getDeclComment(Ctx, *Result.getDeclaration()) + : ""; +} + +std::string getDeclComment(const ASTContext &Ctx, const NamedDecl &Decl) { + if (llvm::isa(Decl)) { // Namespaces often have too many redecls for any particular redecl comment // to be useful. Moreover, we often confuse file headers or generated // comments with namespace comments. Therefore we choose to just ignore // the comments for namespaces. return ""; } - const RawComment *RC = getCompletionComment(Ctx, Decl); - if (!RC) -return ""; - - // Sanity check that the comment does not come from the PCH. We choose to not - // write them into PCH, because they are racy and slow to load. - assert(!Ctx.getSourceManager().isLoadedSourceLocation(RC->getBeginLoc())); - std::string Doc = RC->getFormattedText(Ctx.getSourceManager(), Ctx.getDiagnostics()); - if (!looksLikeDocComment(Doc)) -return ""; - return Doc; -} - -std::string -getParameterDocComment(const ASTContext &Ctx, - const CodeCompleteConsumer::OverloadCandidate &Result, - unsigned ArgIndex, bool CommentsFromHeaders) { - auto *Func = Result.getFunction(); - if (!Func) -return ""; - const RawComment *RC = getParameterComment(Ctx, Result, ArgIndex); + const RawComment *RC = getCompletionComment(Ctx, &Decl); if (!RC) return ""; // Sanity check that the comment does not come from the PCH. We choose to not // write them into PCH, because they are racy and slow to load. assert(!Ctx.getSourceManager().isLoadedSourceLocation(RC->getBeginLoc())); std::string Doc = RC->getFormattedText(Ctx.getSourceManager(), Ctx.getDiagnostics()); - if (!looksLikeDocComment(Doc)) -return ""; - return Doc; + return looksLikeDocComment(Doc) ? Doc : ""; } void getSignature(const CodeCompletionString &CCS, std::string *Signature, Index: clang-tools-extra/trunk/clangd/CodeCompletionStrings.h === --- clang-tools-extra/trunk/clangd/CodeCompletionStrings.h +++ clang-tools-extra/trunk/clangd/CodeCompletionStrings.h @@ -33,18 +33,8 @@ const CodeCompletionResult &Result, bool CommentsFromHeaders); -/// Gets a minimally formatted documentation for parameter of \p Result, -/// corresponding to argument number \p ArgIndex. -/// This currently looks for comments attached to the parameter itself, and -/// doesn't extract them from function documentation. -/// Returns empty string when no comment is available. -/// If \p CommentsFromHeaders parameter is set, only comments from the main -/// file will be returned. It is used to workaround crashes when parsing -/// comments in the stale headers, coming from completion preamble. -std::string -getParameterDocComment(const ASTContext &Ctx, - const CodeCompleteConsumer::OverloadCandidate &Result, - unsigned ArgIndex, bool CommentsFromHeaders); +/// Similar to getDocComment, but returns the comment for a NamedDecl. +std::string getDeclComment(const ASTContext &Ctx, const NamedDecl &D); /// Formats the signature for an item, as a display string and snippet. /// e.g. for const_reference std::vector::at(size_type) const, this returns: Index: clang-tools-extra/trunk/clangd/CodeComplete.cpp === --- clang-tools-extra/trunk/clangd/CodeComplete.cpp +++ clang-tools-extra/trunk/clangd/CodeComplete.cpp @@ -729,8 +729,9 @@ // FIXME: for headers, we need to get a comment from the index. ScoredSignatures.push_back(processOverloadCandidate( Candidate, *CCS, - getParameterDocComment(S.getASTContext(), Candidate, CurrentArg, - /*CommentsFromHeaders=*/false))); + Candidate.getFunction() + ? getDeclComment(S.getASTContext(), *Candidate.getFunction()) +
[PATCH] D50727: [clangd] Fetch documentation from the Index during signature help
This revision was automatically updated to reflect the committed changes. Closed by commit rL340005: [clangd] Fetch documentation from the Index during signature help (authored by ibiryukov, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D50727?vs=160992&id=161189#toc Repository: rL LLVM https://reviews.llvm.org/D50727 Files: clang-tools-extra/trunk/clangd/ClangdServer.cpp clang-tools-extra/trunk/clangd/CodeComplete.cpp clang-tools-extra/trunk/clangd/CodeComplete.h clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp Index: clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp === --- clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp +++ clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp @@ -826,11 +826,19 @@ EXPECT_TRUE(Results.Completions.empty()); } -SignatureHelp signatures(StringRef Text) { +SignatureHelp signatures(StringRef Text, + std::vector IndexSymbols = {}) { + std::unique_ptr Index; + if (!IndexSymbols.empty()) +Index = memIndex(IndexSymbols); + MockFSProvider FS; MockCompilationDatabase CDB; IgnoreDiagnostics DiagConsumer; - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + ClangdServer::Options Opts = ClangdServer::optsForTest(); + Opts.StaticIndex = Index.get(); + + ClangdServer Server(CDB, FS, DiagConsumer, Opts); auto File = testPath("foo.cpp"); Annotations Test(Text); runAddDocument(Server, File, Test.code()); @@ -845,6 +853,7 @@ return false; return true; } +MATCHER_P(SigDoc, Doc, "") { return arg.documentation == Doc; } Matcher Sig(std::string Label, std::vector Params) { @@ -1594,6 +1603,51 @@ ElementsAre(Sig("foo(T, U) -> void", {"T", "U"}))); } +TEST(SignatureHelpTest, IndexDocumentation) { + Symbol::Details DocDetails; + DocDetails.Documentation = "Doc from the index"; + + Symbol Foo0 = sym("foo", index::SymbolKind::Function, "@F@\\0#"); + Foo0.Detail = &DocDetails; + Symbol Foo1 = sym("foo", index::SymbolKind::Function, "@F@\\0#I#"); + Foo1.Detail = &DocDetails; + Symbol Foo2 = sym("foo", index::SymbolKind::Function, "@F@\\0#I#I#"); + + EXPECT_THAT( + signatures(R"cpp( +int foo(); +int foo(double); + +void test() { + foo(^); +} + )cpp", + {Foo0}) + .signatures, + ElementsAre(AllOf(Sig("foo() -> int", {}), SigDoc("Doc from the index")), + AllOf(Sig("foo(double) -> int", {"double"}), SigDoc(""; + + EXPECT_THAT( + signatures(R"cpp( +int foo(); +// Overriden doc from sema +int foo(int); +// Doc from sema +int foo(int, int); + +void test() { + foo(^); +} + )cpp", + {Foo0, Foo1, Foo2}) + .signatures, + ElementsAre(AllOf(Sig("foo() -> int", {}), SigDoc("Doc from the index")), + AllOf(Sig("foo(int) -> int", {"int"}), +SigDoc("Overriden doc from sema")), + AllOf(Sig("foo(int, int) -> int", {"int", "int"}), +SigDoc("Doc from sema"; +} + } // namespace } // namespace clangd } // namespace clang Index: clang-tools-extra/trunk/clangd/CodeComplete.h === --- clang-tools-extra/trunk/clangd/CodeComplete.h +++ clang-tools-extra/trunk/clangd/CodeComplete.h @@ -172,12 +172,11 @@ CodeCompleteOptions Opts); /// Get signature help at a specified \p Pos in \p FileName. -SignatureHelp signatureHelp(PathRef FileName, -const tooling::CompileCommand &Command, -PrecompiledPreamble const *Preamble, -StringRef Contents, Position Pos, -IntrusiveRefCntPtr VFS, -std::shared_ptr PCHs); +SignatureHelp +signatureHelp(PathRef FileName, const tooling::CompileCommand &Command, + PrecompiledPreamble const *Preamble, StringRef Contents, + Position Pos, IntrusiveRefCntPtr VFS, + std::shared_ptr PCHs, SymbolIndex *Index); // For index-based completion, we only consider: // * symbols in namespaces or translation unit scopes (e.g. no class Index: clang-tools-extra/trunk/clangd/ClangdServer.cpp === --- clang-tools-extra/trunk/clangd/ClangdServer.cpp +++ clang-tools-extra/trunk/clangd/ClangdServer.cpp @@ -177,15 +177,16 @@ auto PCHs = this->PCHs; auto FS = FSProvider.getFileSystem(); - auto Action = [Pos, FS, PCHs](Path File, Callback CB, -llvm::Expected IP) { + auto *Index = this->Index; + auto Action = [Pos, FS, PCHs, Index](Path File, Callback CB, +
[PATCH] D50870: Close FileEntries of cached files in ModuleManager::addModule().
This revision was automatically updated to reflect the committed changes. Closed by commit rL340188: Close FileEntries of cached files in ModuleManager::addModule(). (authored by adrian, committed by ). Changed prior to commit: https://reviews.llvm.org/D50870?vs=161119&id=161501#toc Repository: rL LLVM https://reviews.llvm.org/D50870 Files: cfe/trunk/lib/Serialization/ModuleManager.cpp Index: cfe/trunk/lib/Serialization/ModuleManager.cpp === --- cfe/trunk/lib/Serialization/ModuleManager.cpp +++ cfe/trunk/lib/Serialization/ModuleManager.cpp @@ -161,21 +161,24 @@ if (std::unique_ptr Buffer = lookupBuffer(FileName)) { // The buffer was already provided for us. NewModule->Buffer = &PCMCache->addBuffer(FileName, std::move(Buffer)); +// Since the cached buffer is reused, it is safe to close the file +// descriptor that was opened while stat()ing the PCM in +// lookupModuleFile() above, it won't be needed any longer. +Entry->closeFile(); } else if (llvm::MemoryBuffer *Buffer = PCMCache->lookupBuffer(FileName)) { NewModule->Buffer = Buffer; +// As above, the file descriptor is no longer needed. +Entry->closeFile(); } else { // Open the AST file. llvm::ErrorOr> Buf((std::error_code())); if (FileName == "-") { Buf = llvm::MemoryBuffer::getSTDIN(); } else { - // Leave the FileEntry open so if it gets read again by another - // ModuleManager it must be the same underlying file. - // FIXME: Because FileManager::getFile() doesn't guarantee that it will - // give us an open file, this may not be 100% reliable. + // Get a buffer of the file and close the file descriptor when done. Buf = FileMgr.getBufferForFile(NewModule->File, /*IsVolatile=*/false, - /*ShouldClose=*/false); + /*ShouldClose=*/true); } if (!Buf) { Index: cfe/trunk/lib/Serialization/ModuleManager.cpp === --- cfe/trunk/lib/Serialization/ModuleManager.cpp +++ cfe/trunk/lib/Serialization/ModuleManager.cpp @@ -161,21 +161,24 @@ if (std::unique_ptr Buffer = lookupBuffer(FileName)) { // The buffer was already provided for us. NewModule->Buffer = &PCMCache->addBuffer(FileName, std::move(Buffer)); +// Since the cached buffer is reused, it is safe to close the file +// descriptor that was opened while stat()ing the PCM in +// lookupModuleFile() above, it won't be needed any longer. +Entry->closeFile(); } else if (llvm::MemoryBuffer *Buffer = PCMCache->lookupBuffer(FileName)) { NewModule->Buffer = Buffer; +// As above, the file descriptor is no longer needed. +Entry->closeFile(); } else { // Open the AST file. llvm::ErrorOr> Buf((std::error_code())); if (FileName == "-") { Buf = llvm::MemoryBuffer::getSTDIN(); } else { - // Leave the FileEntry open so if it gets read again by another - // ModuleManager it must be the same underlying file. - // FIXME: Because FileManager::getFile() doesn't guarantee that it will - // give us an open file, this may not be 100% reliable. + // Get a buffer of the file and close the file descriptor when done. Buf = FileMgr.getBufferForFile(NewModule->File, /*IsVolatile=*/false, - /*ShouldClose=*/false); + /*ShouldClose=*/true); } if (!Buf) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D47814: Teach libc++ to use native NetBSD's max_align_t
This revision was automatically updated to reflect the committed changes. Closed by commit rCXX340224: Teach libc++ to use native NetBSD's max_align_t (authored by kamil, committed by ). Herald added a subscriber: ldionne. Repository: rCXX libc++ https://reviews.llvm.org/D47814 Files: include/cstddef include/stddef.h Index: include/stddef.h === --- include/stddef.h +++ include/stddef.h @@ -54,7 +54,7 @@ // Re-use the compiler's max_align_t where possible. #if !defined(__CLANG_MAX_ALIGN_T_DEFINED) && !defined(_GCC_MAX_ALIGN_T) && \ -!defined(__DEFINED_max_align_t) +!defined(__DEFINED_max_align_t) && !defined(__NetBSD__) typedef long double max_align_t; #endif Index: include/cstddef === --- include/cstddef +++ include/cstddef @@ -50,7 +50,7 @@ using ::size_t; #if defined(__CLANG_MAX_ALIGN_T_DEFINED) || defined(_GCC_MAX_ALIGN_T) || \ -defined(__DEFINED_max_align_t) +defined(__DEFINED_max_align_t) || defined(__NetBSD__) // Re-use the compiler's max_align_t where possible. using ::max_align_t; #else Index: include/stddef.h === --- include/stddef.h +++ include/stddef.h @@ -54,7 +54,7 @@ // Re-use the compiler's max_align_t where possible. #if !defined(__CLANG_MAX_ALIGN_T_DEFINED) && !defined(_GCC_MAX_ALIGN_T) && \ -!defined(__DEFINED_max_align_t) +!defined(__DEFINED_max_align_t) && !defined(__NetBSD__) typedef long double max_align_t; #endif Index: include/cstddef === --- include/cstddef +++ include/cstddef @@ -50,7 +50,7 @@ using ::size_t; #if defined(__CLANG_MAX_ALIGN_T_DEFINED) || defined(_GCC_MAX_ALIGN_T) || \ -defined(__DEFINED_max_align_t) +defined(__DEFINED_max_align_t) || defined(__NetBSD__) // Re-use the compiler's max_align_t where possible. using ::max_align_t; #else ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D50527: [Parser] Support alternative operator token keyword args in Objective-C++
This revision was automatically updated to reflect the committed changes. Closed by commit rC340301: [Parser] Support alternative operator token keyword args in Objective-C++ (authored by epilk, committed by ). Changed prior to commit: https://reviews.llvm.org/D50527?vs=159995&id=161748#toc Repository: rC Clang https://reviews.llvm.org/D50527 Files: lib/Parse/ParseExpr.cpp test/Parser/message-expr-alt-op.mm Index: test/Parser/message-expr-alt-op.mm === --- test/Parser/message-expr-alt-op.mm +++ test/Parser/message-expr-alt-op.mm @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface WeirdInterface +-(void)allOfThem:(int)a + and:(int)b + and_eq:(int)c + bitand:(int)d + bitor:(int)e + compl:(int)f + not:(int)g + not_eq:(int)h + or:(int)i + or_eq:(int)j + xor:(int)k + xor_eq:(int)l; + +-(void)justAnd:(int)x and:(int)y; +-(void)and; +-(void)and:(int)x; +@end + +void call_it(WeirdInterface *x) { + [x allOfThem:0 + and:0 +and_eq:0 +bitand:0 + bitor:0 + compl:0 + not:0 +not_eq:0 +or:0 + or_eq:0 + xor:0 +xor_eq:0]; + + [x and]; + [x and:0]; + [x &&:0]; // expected-error{{expected expression}}; + [x justAnd:0 and:1]; + [x and: 0 ? : 1]; +} Index: lib/Parse/ParseExpr.cpp === --- lib/Parse/ParseExpr.cpp +++ lib/Parse/ParseExpr.cpp @@ -315,6 +315,19 @@ return LHS; } +// In Objective-C++, alternative operator tokens can be used as keyword args +// in message expressions. Unconsume the token so that it can reinterpreted +// as an identifier in ParseObjCMessageExpressionBody. i.e., we support: +// [foo meth:0 and:0]; +// [foo not_eq]; +if (getLangOpts().ObjC1 && getLangOpts().CPlusPlus && +Tok.isOneOf(tok::colon, tok::r_square) && +OpToken.getIdentifierInfo() != nullptr) { + PP.EnterToken(Tok); + Tok = OpToken; + return LHS; +} + // Special case handling for the ternary operator. ExprResult TernaryMiddle(true); if (NextTokPrec == prec::Conditional) { Index: test/Parser/message-expr-alt-op.mm === --- test/Parser/message-expr-alt-op.mm +++ test/Parser/message-expr-alt-op.mm @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +@interface WeirdInterface +-(void)allOfThem:(int)a + and:(int)b + and_eq:(int)c + bitand:(int)d + bitor:(int)e + compl:(int)f + not:(int)g + not_eq:(int)h + or:(int)i + or_eq:(int)j + xor:(int)k + xor_eq:(int)l; + +-(void)justAnd:(int)x and:(int)y; +-(void)and; +-(void)and:(int)x; +@end + +void call_it(WeirdInterface *x) { + [x allOfThem:0 + and:0 +and_eq:0 +bitand:0 + bitor:0 + compl:0 + not:0 +not_eq:0 +or:0 + or_eq:0 + xor:0 +xor_eq:0]; + + [x and]; + [x and:0]; + [x &&:0]; // expected-error{{expected expression}}; + [x justAnd:0 and:1]; + [x and: 0 ? : 1]; +} Index: lib/Parse/ParseExpr.cpp === --- lib/Parse/ParseExpr.cpp +++ lib/Parse/ParseExpr.cpp @@ -315,6 +315,19 @@ return LHS; } +// In Objective-C++, alternative operator tokens can be used as keyword args +// in message expressions. Unconsume the token so that it can reinterpreted +// as an identifier in ParseObjCMessageExpressionBody. i.e., we support: +// [foo meth:0 and:0]; +// [foo not_eq]; +if (getLangOpts().ObjC1 && getLangOpts().CPlusPlus && +Tok.isOneOf(tok::colon, tok::r_square) && +OpToken.getIdentifierInfo() != nullptr) { + PP.EnterToken(Tok); + Tok = OpToken; + return LHS; +} + // Special case handling for the ternary operator. ExprResult TernaryMiddle(true); if (NextTokPrec == prec::Conditional) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D50994: Add a new flag and attributes to control static destructor registration
This revision was automatically updated to reflect the committed changes. Closed by commit rL340306: Add a new flag and attributes to control static destructor registration (authored by epilk, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D50994?vs=161594&id=161756#toc Repository: rL LLVM https://reviews.llvm.org/D50994 Files: cfe/trunk/include/clang/AST/Decl.h cfe/trunk/include/clang/Basic/Attr.td cfe/trunk/include/clang/Basic/AttrDocs.td cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/include/clang/Basic/LangOptions.def cfe/trunk/include/clang/Driver/Options.td cfe/trunk/lib/AST/Decl.cpp cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp cfe/trunk/lib/Driver/ToolChains/Clang.cpp cfe/trunk/lib/Frontend/CompilerInvocation.cpp cfe/trunk/lib/Sema/SemaDeclAttr.cpp cfe/trunk/lib/Sema/SemaDeclCXX.cpp cfe/trunk/test/CodeGenCXX/always_destroy.cpp cfe/trunk/test/CodeGenCXX/no_destroy.cpp cfe/trunk/test/Misc/pragma-attribute-supported-attributes-list.test cfe/trunk/test/SemaCXX/no_destroy.cpp cfe/trunk/test/SemaCXX/warn-exit-time-destructors.cpp Index: cfe/trunk/include/clang/Basic/AttrDocs.td === --- cfe/trunk/include/clang/Basic/AttrDocs.td +++ cfe/trunk/include/clang/Basic/AttrDocs.td @@ -3486,3 +3486,22 @@ }; }]; } + +def AlwaysDestroyDocs : Documentation { + let Category = DocCatVariable; + let Content = [{ +The ``always_destroy`` attribute specifies that a variable with static or thread +storage duration should have its exit-time destructor run. This attribute is the +default unless clang was invoked with -fno-c++-static-destructors. + }]; +} + +def NoDestroyDocs : Documentation { + let Category = DocCatVariable; + let Content = [{ +The ``no_destroy`` attribute specifies that a variable with static or thread +storage duration shouldn't have its exit-time destructor run. Annotating every +static and thread duration variable with this attribute is equivalent to +invoking clang with -fno-c++-static-destructors. + }]; +} Index: cfe/trunk/include/clang/Basic/Attr.td === --- cfe/trunk/include/clang/Basic/Attr.td +++ cfe/trunk/include/clang/Basic/Attr.td @@ -3009,3 +3009,15 @@ let Subjects = SubjectList<[NonStaticNonConstCXXMethod], ErrorDiag>; let Documentation = [ReinitializesDocs]; } + +def NoDestroy : InheritableAttr { + let Spellings = [Clang<"no_destroy", 0>]; + let Subjects = SubjectList<[Var]>; + let Documentation = [NoDestroyDocs]; +} + +def AlwaysDestroy : InheritableAttr { + let Spellings = [Clang<"always_destroy", 0>]; + let Subjects = SubjectList<[Var]>; + let Documentation = [AlwaysDestroyDocs]; +} Index: cfe/trunk/include/clang/Basic/LangOptions.def === --- cfe/trunk/include/clang/Basic/LangOptions.def +++ cfe/trunk/include/clang/Basic/LangOptions.def @@ -308,6 +308,8 @@ LANGOPT(PaddingOnUnsignedFixedPoint, 1, 0, "unsigned fixed point types having one extra padding bit") +LANGOPT(RegisterStaticDestructors, 1, 1, "Register C++ static destructors") + #undef LANGOPT #undef COMPATIBLE_LANGOPT #undef BENIGN_LANGOPT Index: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td === --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td @@ -1809,6 +1809,10 @@ def note_destructor_type_here : Note< "type %0 is declared here">; +def err_destroy_attr_on_non_static_var : Error< + "%select{no_destroy|always_destroy}0 attribute can only be applied to a" + " variable with static or thread storage duration">; + def err_destructor_template : Error< "destructor cannot be declared as a template">; Index: cfe/trunk/include/clang/Driver/Options.td === --- cfe/trunk/include/clang/Driver/Options.td +++ cfe/trunk/include/clang/Driver/Options.td @@ -898,6 +898,13 @@ Flags<[CC1Option]>, HelpText<"Enable fixed point types">; def fno_fixed_point : Flag<["-"], "fno-fixed-point">, Group, HelpText<"Disable fixed point types">; +def fcxx_static_destructors : Flag<["-"], "fc++-static-destructors">, + Group, + HelpText<"Enable C++ static destructor registration (the default)">; +def fno_cxx_static_destructors : Flag<["-"], "fno-c++-static-destructors">, + Group, + Flags<[CC1Option]>, + HelpText<"Disable C++ static destructor registration">; // Begin sanitizer flags. These should all be core options exposed in all driver // modes. Index: cfe/trunk/include/clang/AST/Decl.h === --- cfe/trunk/include/clang/AST/Decl.h +++ cfe/trunk/include/clang/AST/De
[PATCH] D50994: Add a new flag and attributes to control static destructor registration
This revision was automatically updated to reflect the committed changes. Closed by commit rC340306: Add a new flag and attributes to control static destructor registration (authored by epilk, committed by ). Changed prior to commit: https://reviews.llvm.org/D50994?vs=161594&id=161757#toc Repository: rC Clang https://reviews.llvm.org/D50994 Files: include/clang/AST/Decl.h include/clang/Basic/Attr.td include/clang/Basic/AttrDocs.td include/clang/Basic/DiagnosticSemaKinds.td include/clang/Basic/LangOptions.def include/clang/Driver/Options.td lib/AST/Decl.cpp lib/CodeGen/ItaniumCXXABI.cpp lib/CodeGen/MicrosoftCXXABI.cpp lib/Driver/ToolChains/Clang.cpp lib/Frontend/CompilerInvocation.cpp lib/Sema/SemaDeclAttr.cpp lib/Sema/SemaDeclCXX.cpp test/CodeGenCXX/always_destroy.cpp test/CodeGenCXX/no_destroy.cpp test/Misc/pragma-attribute-supported-attributes-list.test test/SemaCXX/no_destroy.cpp test/SemaCXX/warn-exit-time-destructors.cpp Index: lib/Driver/ToolChains/Clang.cpp === --- lib/Driver/ToolChains/Clang.cpp +++ lib/Driver/ToolChains/Clang.cpp @@ -4832,6 +4832,10 @@ options::OPT_fno_complete_member_pointers, false)) CmdArgs.push_back("-fcomplete-member-pointers"); + if (!Args.hasFlag(options::OPT_fcxx_static_destructors, +options::OPT_fno_cxx_static_destructors, true)) +CmdArgs.push_back("-fno-c++-static-destructors"); + if (Arg *A = Args.getLastArg(options::OPT_moutline, options::OPT_mno_outline)) { if (A->getOption().matches(options::OPT_moutline)) { Index: lib/AST/Decl.cpp === --- lib/AST/Decl.cpp +++ lib/AST/Decl.cpp @@ -2449,6 +2449,12 @@ return hasDefinition(); } +bool VarDecl::isNoDestroy(const ASTContext &Ctx) const { + return hasGlobalStorage() && (hasAttr() || +(!Ctx.getLangOpts().RegisterStaticDestructors && + !hasAttr())); +} + MemberSpecializationInfo *VarDecl::getMemberSpecializationInfo() const { if (isStaticDataMember()) // FIXME: Remove ? Index: lib/Sema/SemaDeclCXX.cpp === --- lib/Sema/SemaDeclCXX.cpp +++ lib/Sema/SemaDeclCXX.cpp @@ -12910,6 +12910,9 @@ if (ClassDecl->hasIrrelevantDestructor()) return; if (ClassDecl->isDependentContext()) return; + if (VD->isNoDestroy(getASTContext())) +return; + CXXDestructorDecl *Destructor = LookupDestructor(ClassDecl); MarkFunctionReferenced(VD->getLocation(), Destructor); CheckDestructorAccess(VD->getLocation(), Destructor, Index: lib/Sema/SemaDeclAttr.cpp === --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -5917,6 +5917,20 @@ AL.getRange(), S.Context, AL.getAttributeSpellingListIndex())); } +static void handleDestroyAttr(Sema &S, Decl *D, const ParsedAttr &A) { + if (!isa(D) || !cast(D)->hasGlobalStorage()) { +S.Diag(D->getLocation(), diag::err_destroy_attr_on_non_static_var) +<< (A.getKind() == ParsedAttr::AT_AlwaysDestroy); +return; + } + + if (A.getKind() == ParsedAttr::AT_AlwaysDestroy) { +handleSimpleAttributeWithExclusions(S, D, A); + } else { +handleSimpleAttributeWithExclusions(S, D, A); + } +} + //===--===// // Top Level Sema Entry Points //===--===// @@ -6587,6 +6601,11 @@ case ParsedAttr::AT_Reinitializes: handleSimpleAttribute(S, D, AL); break; + + case ParsedAttr::AT_AlwaysDestroy: + case ParsedAttr::AT_NoDestroy: +handleDestroyAttr(S, D, AL); +break; } } Index: lib/Frontend/CompilerInvocation.cpp === --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -2772,6 +2772,8 @@ // -fallow-editor-placeholders Opts.AllowEditorPlaceholders = Args.hasArg(OPT_fallow_editor_placeholders); + Opts.RegisterStaticDestructors = !Args.hasArg(OPT_fno_cxx_static_destructors); + if (Arg *A = Args.getLastArg(OPT_fclang_abi_compat_EQ)) { Opts.setClangABICompat(LangOptions::ClangABI::Latest); Index: lib/CodeGen/ItaniumCXXABI.cpp === --- lib/CodeGen/ItaniumCXXABI.cpp +++ lib/CodeGen/ItaniumCXXABI.cpp @@ -2342,6 +2342,9 @@ const VarDecl &D, llvm::Constant *dtor, llvm::Constant *addr) { + if (D.isNoDestroy(CGM.getContext())) +return; + // Use __cxa_atexit if available. if (CGM.getCodeGenOpts().CXAAtExit) return emitGlobalDtorWithCXAAtExit(CGF, dtor, addr, D
[PATCH] D50771: [clang-tblgen] Add -print-records and -dump-json modes.
This revision was automatically updated to reflect the committed changes. Closed by commit rL340390: [clang-tblgen] Add -print-records and -dump-json modes. (authored by statham, committed by ). Herald added a subscriber: llvm-commits. Repository: rL LLVM https://reviews.llvm.org/D50771 Files: cfe/trunk/utils/TableGen/TableGen.cpp Index: cfe/trunk/utils/TableGen/TableGen.cpp === --- cfe/trunk/utils/TableGen/TableGen.cpp +++ cfe/trunk/utils/TableGen/TableGen.cpp @@ -23,6 +23,8 @@ using namespace clang; enum ActionType { + PrintRecords, + DumpJSON, GenClangAttrClasses, GenClangAttrParserStringSwitches, GenClangAttrSubjectMatchRulesParserStringSwitches, @@ -66,6 +68,10 @@ cl::opt Action( cl::desc("Action to perform:"), cl::values( +clEnumValN(PrintRecords, "print-records", + "Print all records to stdout (default)"), +clEnumValN(DumpJSON, "dump-json", + "Dump all records as machine-readable JSON"), clEnumValN(GenClangAttrClasses, "gen-clang-attr-classes", "Generate clang attribute clases"), clEnumValN(GenClangAttrParserStringSwitches, @@ -164,6 +170,12 @@ bool ClangTableGenMain(raw_ostream &OS, RecordKeeper &Records) { switch (Action) { + case PrintRecords: +OS << Records; // No argument, dump all contents +break; + case DumpJSON: +EmitJSON(Records, OS); +break; case GenClangAttrClasses: EmitClangAttrClass(Records, OS); break; Index: cfe/trunk/utils/TableGen/TableGen.cpp === --- cfe/trunk/utils/TableGen/TableGen.cpp +++ cfe/trunk/utils/TableGen/TableGen.cpp @@ -23,6 +23,8 @@ using namespace clang; enum ActionType { + PrintRecords, + DumpJSON, GenClangAttrClasses, GenClangAttrParserStringSwitches, GenClangAttrSubjectMatchRulesParserStringSwitches, @@ -66,6 +68,10 @@ cl::opt Action( cl::desc("Action to perform:"), cl::values( +clEnumValN(PrintRecords, "print-records", + "Print all records to stdout (default)"), +clEnumValN(DumpJSON, "dump-json", + "Dump all records as machine-readable JSON"), clEnumValN(GenClangAttrClasses, "gen-clang-attr-classes", "Generate clang attribute clases"), clEnumValN(GenClangAttrParserStringSwitches, @@ -164,6 +170,12 @@ bool ClangTableGenMain(raw_ostream &OS, RecordKeeper &Records) { switch (Action) { + case PrintRecords: +OS << Records; // No argument, dump all contents +break; + case DumpJSON: +EmitJSON(Records, OS); +break; case GenClangAttrClasses: EmitClangAttrClass(Records, OS); break; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D50847: [clangd] Add callbacks on parsed AST in addition to parsed preambles
This revision was automatically updated to reflect the committed changes. Closed by commit rL340401: [clangd] Add callbacks on parsed AST in addition to parsed preambles (authored by ibiryukov, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D50847?vs=161717&id=161922#toc Repository: rL LLVM https://reviews.llvm.org/D50847 Files: clang-tools-extra/trunk/clangd/ClangdServer.cpp clang-tools-extra/trunk/clangd/ClangdServer.h clang-tools-extra/trunk/clangd/TUScheduler.cpp clang-tools-extra/trunk/clangd/TUScheduler.h clang-tools-extra/trunk/unittests/clangd/TUSchedulerTests.cpp Index: clang-tools-extra/trunk/unittests/clangd/TUSchedulerTests.cpp === --- clang-tools-extra/trunk/unittests/clangd/TUSchedulerTests.cpp +++ clang-tools-extra/trunk/unittests/clangd/TUSchedulerTests.cpp @@ -17,10 +17,11 @@ namespace clang { namespace clangd { +namespace { using ::testing::_; -using ::testing::Each; using ::testing::AnyOf; +using ::testing::Each; using ::testing::Pair; using ::testing::Pointee; using ::testing::UnorderedElementsAre; @@ -44,8 +45,7 @@ TEST_F(TUSchedulerTests, MissingFiles) { TUScheduler S(getDefaultAsyncThreadsCount(), -/*StorePreamblesInMemory=*/true, -/*PreambleParsedCallback=*/nullptr, +/*StorePreamblesInMemory=*/true, noopParsingCallbacks(), /*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(), ASTRetentionPolicy()); @@ -101,8 +101,7 @@ Notification Ready; TUScheduler S( getDefaultAsyncThreadsCount(), -/*StorePreamblesInMemory=*/true, -/*PreambleParsedCallback=*/nullptr, +/*StorePreamblesInMemory=*/true, noopParsingCallbacks(), /*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(), ASTRetentionPolicy()); auto Path = testPath("foo.cpp"); @@ -130,8 +129,7 @@ std::atomic CallbackCount(0); { TUScheduler S(getDefaultAsyncThreadsCount(), - /*StorePreamblesInMemory=*/true, - /*PreambleParsedCallback=*/nullptr, + /*StorePreamblesInMemory=*/true, noopParsingCallbacks(), /*UpdateDebounce=*/std::chrono::seconds(1), ASTRetentionPolicy()); // FIXME: we could probably use timeouts lower than 1 second here. @@ -162,8 +160,7 @@ // Run TUScheduler and collect some stats. { TUScheduler S(getDefaultAsyncThreadsCount(), - /*StorePreamblesInMemory=*/true, - /*PreambleParsedCallback=*/nullptr, + /*StorePreamblesInMemory=*/true, noopParsingCallbacks(), /*UpdateDebounce=*/std::chrono::milliseconds(50), ASTRetentionPolicy()); @@ -261,7 +258,7 @@ Policy.MaxRetainedASTs = 2; TUScheduler S( /*AsyncThreadsCount=*/1, /*StorePreambleInMemory=*/true, - PreambleParsedCallback(), + noopParsingCallbacks(), /*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(), Policy); llvm::StringLiteral SourceContents = R"cpp( @@ -311,7 +308,7 @@ TEST_F(TUSchedulerTests, EmptyPreamble) { TUScheduler S( /*AsyncThreadsCount=*/4, /*StorePreambleInMemory=*/true, - PreambleParsedCallback(), + noopParsingCallbacks(), /*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(), ASTRetentionPolicy()); @@ -358,7 +355,7 @@ // the same time. All reads should get the same non-null preamble. TUScheduler S( /*AsyncThreadsCount=*/4, /*StorePreambleInMemory=*/true, - PreambleParsedCallback(), + noopParsingCallbacks(), /*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(), ASTRetentionPolicy()); auto Foo = testPath("foo.cpp"); @@ -391,7 +388,7 @@ TEST_F(TUSchedulerTests, NoopOnEmptyChanges) { TUScheduler S( /*AsyncThreadsCount=*/getDefaultAsyncThreadsCount(), - /*StorePreambleInMemory=*/true, PreambleParsedCallback(), + /*StorePreambleInMemory=*/true, noopParsingCallbacks(), /*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(), ASTRetentionPolicy()); @@ -444,7 +441,7 @@ TEST_F(TUSchedulerTests, NoChangeDiags) { TUScheduler S( /*AsyncThreadsCount=*/getDefaultAsyncThreadsCount(), - /*StorePreambleInMemory=*/true, PreambleParsedCallback(), + /*StorePreambleInMemory=*/true, noopParsingCallbacks(), /*UpdateDebounce=*/std::chrono::steady_clock::duration::zero(), ASTRetentionPolicy()); @@ -475,5 +472,6 @@ ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(1))); } +} // namespace } // namespace clangd } // namespace clang Index: clang-tools-extra/trunk/clangd/ClangdServer.h === --- clang-tools-extra/trunk/clangd/ClangdServer.h +++ clang-tools-extra/trunk/clangd/ClangdServ
[PATCH] D50889: [clangd] Make FileIndex aware of the main file
This revision was automatically updated to reflect the committed changes. Closed by commit rCTE340404: [clangd] Make FileIndex aware of the main file (authored by ibiryukov, committed by ). Changed prior to commit: https://reviews.llvm.org/D50889?vs=161924&id=161930#toc Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D50889 Files: clangd/ClangdServer.cpp clangd/ClangdServer.h clangd/index/FileIndex.cpp clangd/index/FileIndex.h Index: clangd/ClangdServer.h === --- clangd/ClangdServer.h +++ clangd/ClangdServer.h @@ -99,6 +99,7 @@ /// synchronize access to shared state. ClangdServer(GlobalCompilationDatabase &CDB, FileSystemProvider &FSProvider, DiagnosticsConsumer &DiagConsumer, const Options &Opts); + ~ClangdServer(); /// Set the root path of the workspace. void setRootPath(PathRef RootPath); @@ -200,6 +201,7 @@ formatCode(llvm::StringRef Code, PathRef File, ArrayRef Ranges); + class DynamicIndex; typedef uint64_t DocVersion; void consumeDiagnostics(PathRef File, DocVersion Version, @@ -217,15 +219,14 @@ Path ResourceDir; // The index used to look up symbols. This could be: // - null (all index functionality is optional) - // - the dynamic index owned by ClangdServer (FileIdx) + // - the dynamic index owned by ClangdServer (DynamicIdx) // - the static index passed to the constructor // - a merged view of a static and dynamic index (MergedIndex) SymbolIndex *Index; - // If present, an up-to-date of symbols in open files. Read via Index. - std::unique_ptr FileIdx; - /// Callbacks responsible for updating FileIdx. - std::unique_ptr FileIdxUpdater; - // If present, a merged view of FileIdx and an external index. Read via Index. + /// If present, an up-to-date of symbols in open files. Read via Index. + std::unique_ptr DynamicIdx; + // If present, a merged view of DynamicIdx and an external index. Read via + // Index. std::unique_ptr MergedIndex; // If set, this represents the workspace path. llvm::Optional RootPath; Index: clangd/index/FileIndex.h === --- clangd/index/FileIndex.h +++ clangd/index/FileIndex.h @@ -64,7 +64,11 @@ /// nullptr, this removes all symbols in the file. /// If \p AST is not null, \p PP cannot be null and it should be the /// preprocessor that was used to build \p AST. - void update(PathRef Path, ASTContext *AST, std::shared_ptr PP); + /// If \p TopLevelDecls is set, only these decls are indexed. Otherwise, all + /// top level decls obtained from \p AST are indexed. + void + update(PathRef Path, ASTContext *AST, std::shared_ptr PP, + llvm::Optional> TopLevelDecls = llvm::None); bool fuzzyFind(const FuzzyFindRequest &Req, @@ -86,8 +90,12 @@ /// Retrieves namespace and class level symbols in \p AST. /// Exposed to assist in unit tests. /// If URISchemes is empty, the default schemes in SymbolCollector will be used. -SymbolSlab indexAST(ASTContext &AST, std::shared_ptr PP, -llvm::ArrayRef URISchemes = {}); +/// If \p TopLevelDecls is set, only these decls are indexed. Otherwise, all top +/// level decls obtained from \p AST are indexed. +SymbolSlab +indexAST(ASTContext &AST, std::shared_ptr PP, + llvm::Optional> TopLevelDecls = llvm::None, + llvm::ArrayRef URISchemes = {}); } // namespace clangd } // namespace clang Index: clangd/index/FileIndex.cpp === --- clangd/index/FileIndex.cpp +++ clangd/index/FileIndex.cpp @@ -8,15 +8,16 @@ //===--===// #include "FileIndex.h" -#include "SymbolCollector.h" #include "../Logger.h" +#include "SymbolCollector.h" #include "clang/Index/IndexingAction.h" #include "clang/Lex/Preprocessor.h" namespace clang { namespace clangd { SymbolSlab indexAST(ASTContext &AST, std::shared_ptr PP, +llvm::Optional> TopLevelDecls, llvm::ArrayRef URISchemes) { SymbolCollector::Options CollectorOpts; // FIXME(ioeric): we might also want to collect include headers. We would need @@ -38,10 +39,14 @@ index::IndexingOptions::SystemSymbolFilterKind::DeclarationsOnly; IndexOpts.IndexFunctionLocals = false; - std::vector TopLevelDecls( - AST.getTranslationUnitDecl()->decls().begin(), - AST.getTranslationUnitDecl()->decls().end()); - index::indexTopLevelDecls(AST, TopLevelDecls, Collector, IndexOpts); + std::vector DeclsToIndex; + if (TopLevelDecls) +DeclsToIndex.assign(TopLevelDecls->begin(), TopLevelDecls->end()); + else +DeclsToIndex.assign(AST.getTranslationUnitDecl()->decls().begin(), +AST.getTranslationUnitDecl()->decls().end()); + + index::indexTopLevelDecls(AST, DeclsToIndex, Collector, IndexOpts);
[PATCH] D48027: [analyzer] Improve `CallDescription` to handle c++ method.
This revision was automatically updated to reflect the committed changes. Closed by commit rC340407: [analyzer] Improve `CallDescription` to handle c++ method. (authored by henrywong, committed by ). Changed prior to commit: https://reviews.llvm.org/D48027?vs=161217&id=161938#toc Repository: rC Clang https://reviews.llvm.org/D48027 Files: include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp lib/StaticAnalyzer/Core/CallEvent.cpp Index: include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h === --- include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h +++ include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h @@ -80,24 +80,41 @@ mutable IdentifierInfo *II = nullptr; mutable bool IsLookupDone = false; - StringRef FuncName; + // The list of the qualified names used to identify the specified CallEvent, + // e.g. "{a, b}" represent the qualified names, like "a::b". + std::vector QualifiedName; unsigned RequiredArgs; public: const static unsigned NoArgRequirement = std::numeric_limits::max(); /// Constructs a CallDescription object. /// + /// @param QualifiedName The list of the qualified names of the function that + /// will be matched. It does not require the user to provide the full list of + /// the qualified name. The more details provided, the more accurate the + /// matching. + /// + /// @param RequiredArgs The number of arguments that is expected to match a + /// call. Omit this parameter to match every occurrence of call with a given + /// name regardless the number of arguments. + CallDescription(std::vector QualifiedName, + unsigned RequiredArgs = NoArgRequirement) + : QualifiedName(QualifiedName), RequiredArgs(RequiredArgs) {} + + /// Constructs a CallDescription object. + /// /// @param FuncName The name of the function that will be matched. /// /// @param RequiredArgs The number of arguments that is expected to match a /// call. Omit this parameter to match every occurrence of call with a given /// name regardless the number of arguments. CallDescription(StringRef FuncName, unsigned RequiredArgs = NoArgRequirement) - : FuncName(FuncName), RequiredArgs(RequiredArgs) {} + : CallDescription(std::vector({FuncName}), NoArgRequirement) { + } /// Get the name of the function that this object matches. - StringRef getFunctionName() const { return FuncName; } + StringRef getFunctionName() const { return QualifiedName.back(); } }; template Index: lib/StaticAnalyzer/Core/CallEvent.cpp === --- lib/StaticAnalyzer/Core/CallEvent.cpp +++ lib/StaticAnalyzer/Core/CallEvent.cpp @@ -359,11 +359,38 @@ return false; if (!CD.IsLookupDone) { CD.IsLookupDone = true; -CD.II = &getState()->getStateManager().getContext().Idents.get(CD.FuncName); +CD.II = &getState()->getStateManager().getContext().Idents.get( +CD.getFunctionName()); } const IdentifierInfo *II = getCalleeIdentifier(); if (!II || II != CD.II) return false; + + const Decl *D = getDecl(); + // If CallDescription provides prefix names, use them to improve matching + // accuracy. + if (CD.QualifiedName.size() > 1 && D) { +const DeclContext *Ctx = D->getDeclContext(); +std::vector QualifiedName = CD.QualifiedName; +QualifiedName.pop_back(); +for (; Ctx && isa(Ctx); Ctx = Ctx->getParent()) { + if (const auto *ND = dyn_cast(Ctx)) { +if (!QualifiedName.empty() && ND->getName() == QualifiedName.back()) + QualifiedName.pop_back(); +continue; + } + + if (const auto *RD = dyn_cast(Ctx)) { +if (!QualifiedName.empty() && RD->getName() == QualifiedName.back()) + QualifiedName.pop_back(); +continue; + } +} + +if (!QualifiedName.empty()) + return false; + } + return (CD.RequiredArgs == CallDescription::NoArgRequirement || CD.RequiredArgs == getNumArgs()); } Index: lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp === --- lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp +++ lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp @@ -86,14 +86,20 @@ }; InnerPointerChecker() - : AppendFn("append"), AssignFn("assign"), ClearFn("clear"), -CStrFn("c_str"), DataFn("data"), EraseFn("erase"), InsertFn("insert"), -PopBackFn("pop_back"), PushBackFn("push_back"), ReplaceFn("replace"), -ReserveFn("reserve"), ResizeFn("resize"), -ShrinkToFitFn("shrink_to_fit"), SwapFn("swap") {} - - /// Check if the object of this member function call is a `basic_string`. - bool isCalledOnStringObject(const CXXInstanceCall *ICall) const; + : AppendFn({"std", "basic_string", "append"}), +AssignFn({"std", "basic_st
[PATCH] D51088: [clangd] Get rid of regexes in CanonicalIncludes
This revision was automatically updated to reflect the committed changes. Closed by commit rCTE340410: [clangd] Get rid of regexes in CanonicalIncludes (authored by ibiryukov, committed by ). Changed prior to commit: https://reviews.llvm.org/D51088?vs=161945&id=161946#toc Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D51088 Files: clangd/index/CanonicalIncludes.cpp clangd/index/CanonicalIncludes.h Index: clangd/index/CanonicalIncludes.h === --- clangd/index/CanonicalIncludes.h +++ clangd/index/CanonicalIncludes.h @@ -40,8 +40,10 @@ /// Adds a string-to-string mapping from \p Path to \p CanonicalPath. void addMapping(llvm::StringRef Path, llvm::StringRef CanonicalPath); - /// Maps all files matching \p RE to \p CanonicalPath - void addRegexMapping(llvm::StringRef RE, llvm::StringRef CanonicalPath); + /// Maps files with last path components matching \p Suffix to \p + /// CanonicalPath. + void addPathSuffixMapping(llvm::StringRef Suffix, +llvm::StringRef CanonicalPath); /// Sets the canonical include for any symbol with \p QualifiedName. /// Symbol mappings take precedence over header mappings. @@ -55,17 +57,15 @@ llvm::StringRef QualifiedName) const; private: - // A map from header patterns to header names. This needs to be mutable so - // that we can match again a Regex in a const function member. - // FIXME(ioeric): All the regexes we have so far are suffix matches. The - // performance could be improved by allowing only suffix matches instead of - // arbitrary regexes. - mutable std::vector> - RegexHeaderMappingTable; - // A map from fully qualified symbol names to header names. + /// A map from full include path to a canonical path. + llvm::StringMap FullPathMapping; + /// A map from a suffix (one or components of a path) to a canonical path. + llvm::StringMap SuffixHeaderMapping; + /// Maximum number of path components stored in a key of SuffixHeaderMapping. + /// Used to reduce the number of lookups into SuffixHeaderMapping. + int MaxSuffixComponents = 0; + /// A map from fully qualified symbol names to header names. llvm::StringMap SymbolMapping; - // Guards Regex matching as it's not thread-safe. - mutable std::mutex RegexMutex; }; /// Returns a CommentHandler that parses pragma comment on include files to Index: clangd/index/CanonicalIncludes.cpp === --- clangd/index/CanonicalIncludes.cpp +++ clangd/index/CanonicalIncludes.cpp @@ -10,23 +10,26 @@ #include "CanonicalIncludes.h" #include "../Headers.h" #include "clang/Driver/Types.h" -#include "llvm/Support/Regex.h" +#include "llvm/Support/Path.h" +#include namespace clang { namespace clangd { namespace { const char IWYUPragma[] = "// IWYU pragma: private, include "; } // namespace -void CanonicalIncludes::addMapping(llvm::StringRef Path, - llvm::StringRef CanonicalPath) { - addRegexMapping((llvm::Twine("^") + llvm::Regex::escape(Path) + "$").str(), - CanonicalPath); +void CanonicalIncludes::addPathSuffixMapping(llvm::StringRef Suffix, + llvm::StringRef CanonicalPath) { + int Components = std::distance(llvm::sys::path::begin(Suffix), + llvm::sys::path::end(Suffix)); + MaxSuffixComponents = std::max(MaxSuffixComponents, Components); + SuffixHeaderMapping[Suffix] = CanonicalPath; } -void CanonicalIncludes::addRegexMapping(llvm::StringRef RE, -llvm::StringRef CanonicalPath) { - this->RegexHeaderMappingTable.emplace_back(llvm::Regex(RE), CanonicalPath); +void CanonicalIncludes::addMapping(llvm::StringRef Path, + llvm::StringRef CanonicalPath) { + FullPathMapping[Path] = CanonicalPath; } void CanonicalIncludes::addSymbolMapping(llvm::StringRef QualifiedName, @@ -41,7 +44,6 @@ auto SE = SymbolMapping.find(QualifiedName); if (SE != SymbolMapping.end()) return SE->second; - std::lock_guard Lock(RegexMutex); // Find the first header such that the extension is not '.inc', and isn't a // recognized non-header file auto I = @@ -62,13 +64,19 @@ if ((ExtType != driver::types::TY_INVALID) && !driver::types::onlyPrecompileType(ExtType)) return Headers[0]; - for (auto &Entry : RegexHeaderMappingTable) { -#ifndef NDEBUG -std::string Dummy; -assert(Entry.first.isValid(Dummy) && "Regex should never be invalid!"); -#endif -if (Entry.first.match(Header)) - return Entry.second; + + auto MapIt = FullPathMapping.find(Header); + if (MapIt != FullPathMapping.end()) +return MapIt->second; + + int Components = 1; + for (auto It = llvm::sys::path::rbegin(Header), +End = llvm::sys::path::rend(Header); + It != End && Co
[PATCH] D46320: Remove \brief commands from doxygen comments.
This revision was automatically updated to reflect the committed changes. Closed by commit rC331834: Remove \brief commands from doxygen comments. (authored by adrian, committed by ). Changed prior to commit: https://reviews.llvm.org/D46320?vs=144736&id=145831#toc Repository: rC Clang https://reviews.llvm.org/D46320 Files: docs/LibFormat.rst docs/doxygen.cfg.in include/clang-c/BuildSystem.h include/clang-c/CXCompilationDatabase.h include/clang-c/CXErrorCode.h include/clang-c/CXString.h include/clang-c/Documentation.h include/clang-c/Index.h include/clang/ARCMigrate/ARCMT.h include/clang/ARCMigrate/ARCMTActions.h include/clang/AST/APValue.h include/clang/AST/ASTConsumer.h include/clang/AST/ASTContext.h include/clang/AST/ASTDiagnostic.h include/clang/AST/ASTFwd.h include/clang/AST/ASTImporter.h include/clang/AST/ASTLambda.h include/clang/AST/ASTMutationListener.h include/clang/AST/ASTTypeTraits.h include/clang/AST/ASTUnresolvedSet.h include/clang/AST/Attr.h include/clang/AST/Availability.h include/clang/AST/CXXInheritance.h include/clang/AST/CanonicalType.h include/clang/AST/CommentBriefParser.h include/clang/AST/CommentCommandTraits.h include/clang/AST/CommentLexer.h include/clang/AST/CommentSema.h include/clang/AST/ComparisonCategories.h include/clang/AST/DataCollection.h include/clang/AST/Decl.h include/clang/AST/DeclBase.h include/clang/AST/DeclCXX.h include/clang/AST/DeclContextInternals.h include/clang/AST/DeclObjC.h include/clang/AST/DeclOpenMP.h include/clang/AST/DeclTemplate.h include/clang/AST/DeclVisitor.h include/clang/AST/DeclarationName.h include/clang/AST/EvaluatedExprVisitor.h include/clang/AST/Expr.h include/clang/AST/ExprCXX.h include/clang/AST/ExprObjC.h include/clang/AST/ExprOpenMP.h include/clang/AST/ExternalASTSource.h include/clang/AST/LambdaCapture.h include/clang/AST/LocInfoType.h include/clang/AST/Mangle.h include/clang/AST/MangleNumberingContext.h include/clang/AST/NSAPI.h include/clang/AST/NestedNameSpecifier.h include/clang/AST/OpenMPClause.h include/clang/AST/OperationKinds.def include/clang/AST/OperationKinds.h include/clang/AST/ParentMap.h include/clang/AST/PrettyPrinter.h include/clang/AST/QualTypeNames.h include/clang/AST/RawCommentList.h include/clang/AST/RecordLayout.h include/clang/AST/RecursiveASTVisitor.h include/clang/AST/Redeclarable.h include/clang/AST/SelectorLocationsKind.h include/clang/AST/Stmt.h include/clang/AST/StmtCXX.h include/clang/AST/StmtObjC.h include/clang/AST/StmtOpenMP.h include/clang/AST/StmtVisitor.h include/clang/AST/TemplateBase.h include/clang/AST/TemplateName.h include/clang/AST/Type.h include/clang/AST/TypeLoc.h include/clang/AST/TypeOrdering.h include/clang/AST/TypeVisitor.h include/clang/AST/UnresolvedSet.h include/clang/AST/VTTBuilder.h include/clang/AST/VTableBuilder.h include/clang/ASTMatchers/ASTMatchFinder.h include/clang/ASTMatchers/ASTMatchers.h include/clang/ASTMatchers/ASTMatchersInternal.h include/clang/ASTMatchers/ASTMatchersMacros.h include/clang/ASTMatchers/Dynamic/Diagnostics.h include/clang/ASTMatchers/Dynamic/Parser.h include/clang/ASTMatchers/Dynamic/Registry.h include/clang/ASTMatchers/Dynamic/VariantValue.h include/clang/Analysis/Analyses/Consumed.h include/clang/Analysis/Analyses/Dominators.h include/clang/Analysis/Analyses/FormatString.h include/clang/Analysis/Analyses/PostOrderCFGView.h include/clang/Analysis/Analyses/ThreadSafety.h include/clang/Analysis/Analyses/ThreadSafetyCommon.h include/clang/Analysis/Analyses/ThreadSafetyLogical.h include/clang/Analysis/AnalysisDeclContext.h include/clang/Analysis/CFG.h include/clang/Analysis/CallGraph.h include/clang/Analysis/CodeInjector.h include/clang/Analysis/ProgramPoint.h include/clang/Basic/ABI.h include/clang/Basic/AddressSpaces.h include/clang/Basic/AlignedAllocation.h include/clang/Basic/AllDiagnostics.h include/clang/Basic/AttrKinds.h include/clang/Basic/AttrSubjectMatchRules.h include/clang/Basic/Attributes.h include/clang/Basic/Builtins.h include/clang/Basic/BuiltinsWebAssembly.def include/clang/Basic/CapturedStmt.h include/clang/Basic/CommentOptions.h include/clang/Basic/Diagnostic.h include/clang/Basic/DiagnosticError.h include/clang/Basic/DiagnosticIDs.h include/clang/Basic/DiagnosticOptions.h include/clang/Basic/ExceptionSpecificationType.h include/clang/Basic/ExpressionTraits.h include/clang/Basic/FileManager.h include/clang/Basic/FileSystemOptions.h include/clang/Basic/FileSystemStatCache.h include/clang/Basic/IdentifierTable.h include/clang/Basic/LLVM.h include/clang/Basic/Lambda.h include/clang/Basic/LangOptions.def include/clang/Basic/LangOptions.h include/clang/Basic/Linkage.h include/clang/Basic/MacroBuilder.h include/clang/Basic/Module.h include/clang/Basic/ObjCRuntime.h include/clang/Basic/OpenCLOp
[PATCH] D46320: Remove \brief commands from doxygen comments.
This revision was automatically updated to reflect the committed changes. Closed by commit rL331834: Remove \brief commands from doxygen comments. (authored by adrian, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D46320?vs=144736&id=145832#toc Repository: rL LLVM https://reviews.llvm.org/D46320 Files: cfe/trunk/docs/LibFormat.rst cfe/trunk/docs/doxygen.cfg.in cfe/trunk/include/clang-c/BuildSystem.h cfe/trunk/include/clang-c/CXCompilationDatabase.h cfe/trunk/include/clang-c/CXErrorCode.h cfe/trunk/include/clang-c/CXString.h cfe/trunk/include/clang-c/Documentation.h cfe/trunk/include/clang-c/Index.h cfe/trunk/include/clang/ARCMigrate/ARCMT.h cfe/trunk/include/clang/ARCMigrate/ARCMTActions.h cfe/trunk/include/clang/AST/APValue.h cfe/trunk/include/clang/AST/ASTConsumer.h cfe/trunk/include/clang/AST/ASTContext.h cfe/trunk/include/clang/AST/ASTDiagnostic.h cfe/trunk/include/clang/AST/ASTFwd.h cfe/trunk/include/clang/AST/ASTImporter.h cfe/trunk/include/clang/AST/ASTLambda.h cfe/trunk/include/clang/AST/ASTMutationListener.h cfe/trunk/include/clang/AST/ASTTypeTraits.h cfe/trunk/include/clang/AST/ASTUnresolvedSet.h cfe/trunk/include/clang/AST/Attr.h cfe/trunk/include/clang/AST/Availability.h cfe/trunk/include/clang/AST/CXXInheritance.h cfe/trunk/include/clang/AST/CanonicalType.h cfe/trunk/include/clang/AST/CommentBriefParser.h cfe/trunk/include/clang/AST/CommentCommandTraits.h cfe/trunk/include/clang/AST/CommentLexer.h cfe/trunk/include/clang/AST/CommentSema.h cfe/trunk/include/clang/AST/ComparisonCategories.h cfe/trunk/include/clang/AST/DataCollection.h cfe/trunk/include/clang/AST/Decl.h cfe/trunk/include/clang/AST/DeclBase.h cfe/trunk/include/clang/AST/DeclCXX.h cfe/trunk/include/clang/AST/DeclContextInternals.h cfe/trunk/include/clang/AST/DeclObjC.h cfe/trunk/include/clang/AST/DeclOpenMP.h cfe/trunk/include/clang/AST/DeclTemplate.h cfe/trunk/include/clang/AST/DeclVisitor.h cfe/trunk/include/clang/AST/DeclarationName.h cfe/trunk/include/clang/AST/EvaluatedExprVisitor.h cfe/trunk/include/clang/AST/Expr.h cfe/trunk/include/clang/AST/ExprCXX.h cfe/trunk/include/clang/AST/ExprObjC.h cfe/trunk/include/clang/AST/ExprOpenMP.h cfe/trunk/include/clang/AST/ExternalASTSource.h cfe/trunk/include/clang/AST/LambdaCapture.h cfe/trunk/include/clang/AST/LocInfoType.h cfe/trunk/include/clang/AST/Mangle.h cfe/trunk/include/clang/AST/MangleNumberingContext.h cfe/trunk/include/clang/AST/NSAPI.h cfe/trunk/include/clang/AST/NestedNameSpecifier.h cfe/trunk/include/clang/AST/OpenMPClause.h cfe/trunk/include/clang/AST/OperationKinds.def cfe/trunk/include/clang/AST/OperationKinds.h cfe/trunk/include/clang/AST/ParentMap.h cfe/trunk/include/clang/AST/PrettyPrinter.h cfe/trunk/include/clang/AST/QualTypeNames.h cfe/trunk/include/clang/AST/RawCommentList.h cfe/trunk/include/clang/AST/RecordLayout.h cfe/trunk/include/clang/AST/RecursiveASTVisitor.h cfe/trunk/include/clang/AST/Redeclarable.h cfe/trunk/include/clang/AST/SelectorLocationsKind.h cfe/trunk/include/clang/AST/Stmt.h cfe/trunk/include/clang/AST/StmtCXX.h cfe/trunk/include/clang/AST/StmtObjC.h cfe/trunk/include/clang/AST/StmtOpenMP.h cfe/trunk/include/clang/AST/StmtVisitor.h cfe/trunk/include/clang/AST/TemplateBase.h cfe/trunk/include/clang/AST/TemplateName.h cfe/trunk/include/clang/AST/Type.h cfe/trunk/include/clang/AST/TypeLoc.h cfe/trunk/include/clang/AST/TypeOrdering.h cfe/trunk/include/clang/AST/TypeVisitor.h cfe/trunk/include/clang/AST/UnresolvedSet.h cfe/trunk/include/clang/AST/VTTBuilder.h cfe/trunk/include/clang/AST/VTableBuilder.h cfe/trunk/include/clang/ASTMatchers/ASTMatchFinder.h cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h cfe/trunk/include/clang/ASTMatchers/ASTMatchersMacros.h cfe/trunk/include/clang/ASTMatchers/Dynamic/Diagnostics.h cfe/trunk/include/clang/ASTMatchers/Dynamic/Parser.h cfe/trunk/include/clang/ASTMatchers/Dynamic/Registry.h cfe/trunk/include/clang/ASTMatchers/Dynamic/VariantValue.h cfe/trunk/include/clang/Analysis/Analyses/Consumed.h cfe/trunk/include/clang/Analysis/Analyses/Dominators.h cfe/trunk/include/clang/Analysis/Analyses/FormatString.h cfe/trunk/include/clang/Analysis/Analyses/PostOrderCFGView.h cfe/trunk/include/clang/Analysis/Analyses/ThreadSafety.h cfe/trunk/include/clang/Analysis/Analyses/ThreadSafetyCommon.h cfe/trunk/include/clang/Analysis/Analyses/ThreadSafetyLogical.h cfe/trunk/include/clang/Analysis/AnalysisDeclContext.h cfe/trunk/include/clang/Analysis/CFG.h cfe/trunk/include/clang/Analysis/CallGraph.h cfe/trunk/include/clang/Analysis/CodeInjector.h cfe/trunk/include/clang/Analysis/ProgramPoint.h cfe/trunk/include/clang/Basic/ABI.h cfe/trunk/include/clang/Basic/AddressSpaces.h cfe/trunk/include/clang/Basic/AlignedA
[PATCH] D45045: [DebugInfo] Generate debug information for labels.
This revision was not accepted when it landed; it landed in state "Needs Review". This revision was automatically updated to reflect the committed changes. Closed by commit rL331843: [DebugInfo] Generate debug information for labels. (authored by shiva, committed by ). Changed prior to commit: https://reviews.llvm.org/D45045?vs=143243&id=145849#toc Repository: rL LLVM https://reviews.llvm.org/D45045 Files: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp cfe/trunk/lib/CodeGen/CGDebugInfo.h cfe/trunk/lib/CodeGen/CGStmt.cpp cfe/trunk/test/CodeGen/backend-unsupported-error.ll cfe/trunk/test/CodeGen/debug-label-inline.c cfe/trunk/test/CodeGen/debug-label.c Index: cfe/trunk/lib/CodeGen/CGDebugInfo.h === --- cfe/trunk/lib/CodeGen/CGDebugInfo.h +++ cfe/trunk/lib/CodeGen/CGDebugInfo.h @@ -396,6 +396,9 @@ llvm::Value *AI, CGBuilderTy &Builder); + /// Emit call to \c llvm.dbg.label for an label. + void EmitLabel(const LabelDecl *D, CGBuilderTy &Builder); + /// Emit call to \c llvm.dbg.declare for an imported variable /// declaration in a block. void EmitDeclareOfBlockDeclRefVariable(const VarDecl *variable, Index: cfe/trunk/lib/CodeGen/CGStmt.cpp === --- cfe/trunk/lib/CodeGen/CGStmt.cpp +++ cfe/trunk/lib/CodeGen/CGStmt.cpp @@ -531,6 +531,16 @@ } EmitBlock(Dest.getBlock()); + + // Emit debug info for labels. + if (CGDebugInfo *DI = getDebugInfo()) { +if (CGM.getCodeGenOpts().getDebugInfo() >= +codegenoptions::LimitedDebugInfo) { + DI->setLocation(D->getLocation()); + DI->EmitLabel(D, Builder); +} + } + incrementProfileCounter(D->getStmt()); } Index: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp === --- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp +++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp @@ -3647,6 +3647,32 @@ return EmitDeclare(VD, Storage, llvm::None, Builder); } +void CGDebugInfo::EmitLabel(const LabelDecl *D, CGBuilderTy &Builder) { + assert(DebugKind >= codegenoptions::LimitedDebugInfo); + assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!"); + + if (D->hasAttr()) +return; + + auto *Scope = cast(LexicalBlockStack.back()); + llvm::DIFile *Unit = getOrCreateFile(D->getLocation()); + + // Get location information. + unsigned Line = getLineNumber(D->getLocation()); + unsigned Column = getColumnNumber(D->getLocation()); + + StringRef Name = D->getName(); + + // Create the descriptor for the label. + auto *L = + DBuilder.createLabel(Scope, Name, Unit, Line, CGM.getLangOpts().Optimize); + + // Insert an llvm.dbg.label into the current block. + DBuilder.insertLabel(L, + llvm::DebugLoc::get(Line, Column, Scope, CurInlinedAt), + Builder.GetInsertBlock()); +} + llvm::DIType *CGDebugInfo::CreateSelfType(const QualType &QualTy, llvm::DIType *Ty) { llvm::DIType *CachedTy = getTypeOrNull(QualTy); Index: cfe/trunk/test/CodeGen/debug-label.c === --- cfe/trunk/test/CodeGen/debug-label.c +++ cfe/trunk/test/CodeGen/debug-label.c @@ -0,0 +1,16 @@ +// This test will test the correstness of generating DILabel and +// llvm.dbg.label for labels. +// +// RUN: %clang_cc1 -emit-llvm %s -o - -emit-llvm -debug-info-kind=limited | FileCheck %s + +int f1(int a, int b) { + int sum; + +top: + // CHECK: call void @llvm.dbg.label(metadata [[LABEL_METADATA:!.*]]), !dbg [[LABEL_LOCATION:!.*]] + sum = a + b; + return sum; +} + +// CHECK: [[LABEL_METADATA]] = !DILabel({{.*}}, name: "top", {{.*}}, line: 9) +// CHECK: [[LABEL_LOCATION]] = !DILocation(line: 9, Index: cfe/trunk/test/CodeGen/backend-unsupported-error.ll === --- cfe/trunk/test/CodeGen/backend-unsupported-error.ll +++ cfe/trunk/test/CodeGen/backend-unsupported-error.ll @@ -30,11 +30,11 @@ !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.9.0", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2) !1 = !DIFile(filename: "test.c", directory: "") !2 = !{} -!4 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 2, type: !5, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: false, unit: !0, variables: !2) +!4 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 2, type: !5, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: false, unit: !0, retainedNodes: !2) !5 = !DISubroutineType(types: !6) !6 = !{!7} !7 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed) -!8 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 3, type: !5, isLocal: false, isDe
[PATCH] D46049: [OpenCL] Add constant address space to __func__ in AST
This revision was automatically updated to reflect the committed changes. Closed by commit rL331877: [OpenCL] Add constant address space to __func__ in AST. (authored by stulova, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D46049?vs=145000&id=145907#toc Repository: rL LLVM https://reviews.llvm.org/D46049 Files: cfe/trunk/include/clang/AST/ASTContext.h cfe/trunk/lib/AST/ASTContext.cpp cfe/trunk/lib/AST/Expr.cpp cfe/trunk/lib/Sema/SemaExpr.cpp cfe/trunk/test/CodeGenOpenCL/str_literals.cl cfe/trunk/test/SemaOpenCL/predefined-expr.cl Index: cfe/trunk/include/clang/AST/ASTContext.h === --- cfe/trunk/include/clang/AST/ASTContext.h +++ cfe/trunk/include/clang/AST/ASTContext.h @@ -1348,6 +1348,8 @@ return getFunctionTypeInternal(ResultTy, Args, EPI, false); } + QualType adjustStringLiteralBaseType(QualType StrLTy) const; + private: /// Return a normal function type with a typed argument list. QualType getFunctionTypeInternal(QualType ResultTy, ArrayRef Args, Index: cfe/trunk/test/SemaOpenCL/predefined-expr.cl === --- cfe/trunk/test/SemaOpenCL/predefined-expr.cl +++ cfe/trunk/test/SemaOpenCL/predefined-expr.cl @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 %s -verify +// RUN: %clang_cc1 %s -verify -cl-std=CL2.0 + +void f() { + char *f1 = __func__; //expected-error-re{{initializing '{{__generic char|char}} *' with an expression of type 'const __constant char *' changes address space of pointer}} + constant char *f2 = __func__; //expected-warning{{initializing '__constant char *' with an expression of type 'const __constant char [2]' discards qualifiers}} + constant const char *f3 = __func__; +} Index: cfe/trunk/test/CodeGenOpenCL/str_literals.cl === --- cfe/trunk/test/CodeGenOpenCL/str_literals.cl +++ cfe/trunk/test/CodeGenOpenCL/str_literals.cl @@ -1,9 +1,15 @@ // RUN: %clang_cc1 %s -cl-opt-disable -emit-llvm -o - -ffake-address-space-map | FileCheck %s -__constant char * __constant x = "hello world"; -__constant char * __constant y = "hello world"; +__constant char *__constant x = "hello world"; +__constant char *__constant y = "hello world"; -// CHECK: unnamed_addr addrspace(2) constant +// CHECK: unnamed_addr addrspace(2) constant{{.*}}"hello world\00" // CHECK-NOT: addrspace(2) unnamed_addr constant // CHECK: @x = {{(dso_local )?}}addrspace(2) constant i8 addrspace(2)* // CHECK: @y = {{(dso_local )?}}addrspace(2) constant i8 addrspace(2)* +// CHECK: unnamed_addr addrspace(2) constant{{.*}}"f\00" + +void f() { + //CHECK: store i8 addrspace(2)* {{.*}}, i8 addrspace(2)** + constant const char *f3 = __func__; +} Index: cfe/trunk/lib/AST/ASTContext.cpp === --- cfe/trunk/lib/AST/ASTContext.cpp +++ cfe/trunk/lib/AST/ASTContext.cpp @@ -3621,6 +3621,12 @@ return QualType(New, 0); } +QualType ASTContext::adjustStringLiteralBaseType(QualType Ty) const { + // OpenCL v1.1 s6.5.3: a string literal is in the constant address space. + return LangOpts.OpenCL ? getAddrSpaceQualType(Ty, LangAS::opencl_constant) + : Ty; +} + QualType ASTContext::getReadPipeType(QualType T) const { return getPipeType(T, true); } Index: cfe/trunk/lib/AST/Expr.cpp === --- cfe/trunk/lib/AST/Expr.cpp +++ cfe/trunk/lib/AST/Expr.cpp @@ -881,7 +881,8 @@ void *Mem = C.Allocate(sizeof(StringLiteral) + sizeof(SourceLocation) * (NumStrs - 1), alignof(StringLiteral)); - StringLiteral *SL = new (Mem) StringLiteral(QualType()); + StringLiteral *SL = + new (Mem) StringLiteral(C.adjustStringLiteralBaseType(QualType())); SL->CharByteWidth = 0; SL->Length = 0; SL->NumConcatenated = NumStrs; Index: cfe/trunk/lib/Sema/SemaExpr.cpp === --- cfe/trunk/lib/Sema/SemaExpr.cpp +++ cfe/trunk/lib/Sema/SemaExpr.cpp @@ -1554,17 +1554,14 @@ if (getLangOpts().CPlusPlus || getLangOpts().ConstStrings) CharTyConst.addConst(); + CharTyConst = Context.adjustStringLiteralBaseType(CharTyConst); + // Get an array type for the string, according to C99 6.4.5. This includes // the nul terminator character as well as the string length for pascal // strings. - QualType StrTy = Context.getConstantArrayType(CharTyConst, - llvm::APInt(32, Literal.GetNumStringChars()+1), - ArrayType::Normal, 0); - - // OpenCL v1.1 s6.5.3: a string literal is in the constant address space. - if (getLangOpts().OpenCL) { -StrTy = Context.getAddrSpaceQualType(StrTy, LangAS::opencl_constant); - } + QualType StrTy = Context.getConstantArrayType( + CharTyC
[PATCH] D46332: [X86] Only enable the __ud2 and __int2c builtins if intrin.h has been included.
This revision was automatically updated to reflect the committed changes. Closed by commit rC331893: [X86] Only enable the __ud2 and __int2c builtins if intrin.h has been included. (authored by ctopper, committed by ). Repository: rC Clang https://reviews.llvm.org/D46332 Files: include/clang/Basic/BuiltinsX86.def Index: include/clang/Basic/BuiltinsX86.def === --- include/clang/Basic/BuiltinsX86.def +++ include/clang/Basic/BuiltinsX86.def @@ -1899,8 +1899,8 @@ TARGET_HEADER_BUILTIN(_AddressOfReturnAddress, "v*", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(__stosb, "vUc*Ucz", "nh", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(__int2c, "v", "nr", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(__ud2, "v", "nr", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__int2c, "v", "nhr", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__ud2, "v", "nhr", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(__readfsbyte, "UcUNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(__readfsword, "UsUNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") Index: include/clang/Basic/BuiltinsX86.def === --- include/clang/Basic/BuiltinsX86.def +++ include/clang/Basic/BuiltinsX86.def @@ -1899,8 +1899,8 @@ TARGET_HEADER_BUILTIN(_AddressOfReturnAddress, "v*", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(__stosb, "vUc*Ucz", "nh", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(__int2c, "v", "nr", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(__ud2, "v", "nr", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__int2c, "v", "nhr", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__ud2, "v", "nhr", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(__readfsbyte, "UcUNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(__readfsword, "UsUNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46656: [Builtins] Improve the IR emitted for MSVC compatible rotr/rotl builtins to match what the middle and backends understand
This revision was automatically updated to reflect the committed changes. Closed by commit rL331943: [Builtins] Improve the IR emitted for MSVC compatible rotr/rotl builtins to… (authored by ctopper, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D46656?vs=145979&id=146036#toc Repository: rL LLVM https://reviews.llvm.org/D46656 Files: cfe/trunk/lib/CodeGen/CGBuiltin.cpp cfe/trunk/test/CodeGen/ms-intrinsics-rotations.c Index: cfe/trunk/lib/CodeGen/CGBuiltin.cpp === --- cfe/trunk/lib/CodeGen/CGBuiltin.cpp +++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp @@ -1409,20 +1409,14 @@ llvm::Type *ArgType = Val->getType(); Shift = Builder.CreateIntCast(Shift, ArgType, false); -unsigned ArgWidth = cast(ArgType)->getBitWidth(); -Value *ArgTypeSize = llvm::ConstantInt::get(ArgType, ArgWidth); -Value *ArgZero = llvm::Constant::getNullValue(ArgType); - +unsigned ArgWidth = ArgType->getIntegerBitWidth(); Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1); -Shift = Builder.CreateAnd(Shift, Mask); -Value *LeftShift = Builder.CreateSub(ArgTypeSize, Shift); - -Value *RightShifted = Builder.CreateLShr(Val, Shift); -Value *LeftShifted = Builder.CreateShl(Val, LeftShift); -Value *Rotated = Builder.CreateOr(LeftShifted, RightShifted); -Value *ShiftIsZero = Builder.CreateICmpEQ(Shift, ArgZero); -Value *Result = Builder.CreateSelect(ShiftIsZero, Val, Rotated); +Value *RightShiftAmt = Builder.CreateAnd(Shift, Mask); +Value *RightShifted = Builder.CreateLShr(Val, RightShiftAmt); +Value *LeftShiftAmt = Builder.CreateAnd(Builder.CreateNeg(Shift), Mask); +Value *LeftShifted = Builder.CreateShl(Val, LeftShiftAmt); +Value *Result = Builder.CreateOr(LeftShifted, RightShifted); return RValue::get(Result); } case Builtin::BI_rotl8: @@ -1435,20 +1429,14 @@ llvm::Type *ArgType = Val->getType(); Shift = Builder.CreateIntCast(Shift, ArgType, false); -unsigned ArgWidth = cast(ArgType)->getBitWidth(); -Value *ArgTypeSize = llvm::ConstantInt::get(ArgType, ArgWidth); -Value *ArgZero = llvm::Constant::getNullValue(ArgType); - +unsigned ArgWidth = ArgType->getIntegerBitWidth(); Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1); -Shift = Builder.CreateAnd(Shift, Mask); -Value *RightShift = Builder.CreateSub(ArgTypeSize, Shift); - -Value *LeftShifted = Builder.CreateShl(Val, Shift); -Value *RightShifted = Builder.CreateLShr(Val, RightShift); -Value *Rotated = Builder.CreateOr(LeftShifted, RightShifted); -Value *ShiftIsZero = Builder.CreateICmpEQ(Shift, ArgZero); -Value *Result = Builder.CreateSelect(ShiftIsZero, Val, Rotated); +Value *LeftShiftAmt = Builder.CreateAnd(Shift, Mask); +Value *LeftShifted = Builder.CreateShl(Val, LeftShiftAmt); +Value *RightShiftAmt = Builder.CreateAnd(Builder.CreateNeg(Shift), Mask); +Value *RightShifted = Builder.CreateLShr(Val, RightShiftAmt); +Value *Result = Builder.CreateOr(LeftShifted, RightShifted); return RValue::get(Result); } case Builtin::BI__builtin_unpredictable: { Index: cfe/trunk/test/CodeGen/ms-intrinsics-rotations.c === --- cfe/trunk/test/CodeGen/ms-intrinsics-rotations.c +++ cfe/trunk/test/CodeGen/ms-intrinsics-rotations.c @@ -30,69 +30,64 @@ return _rotl8(value, shift); } // CHECK: i8 @test_rotl8 -// CHECK: [[SHIFT:%[0-9]+]] = and i8 %{{[0-9]+}}, 7 -// CHECK: [[NEGSHIFT:%[0-9]+]] = sub i8 8, [[SHIFT]] -// CHECK: [[HIGH:%[0-9]+]] = shl i8 [[VALUE:%[0-9]+]], [[SHIFT]] -// CHECK: [[LOW:%[0-9]+]] = lshr i8 [[VALUE]], [[NEGSHIFT]] -// CHECK: [[ROTATED:%[0-9]+]] = or i8 [[HIGH]], [[LOW]] -// CHECK: [[ISZERO:%[0-9]+]] = icmp eq i8 [[SHIFT]], 0 -// CHECK: [[RESULT:%[0-9]+]] = select i1 [[ISZERO]], i8 [[VALUE]], i8 [[ROTATED]] +// CHECK: [[LSHIFT:%[0-9]+]] = and i8 [[SHIFT:%[0-9]+]], 7 +// CHECK: [[HIGH:%[0-9]+]] = shl i8 [[VALUE:%[0-9]+]], [[LSHIFT]] +// CHECK: [[NEGATE:%[0-9]+]] = sub i8 0, [[SHIFT]] +// CHECK: [[RSHIFT:%[0-9]+]] = and i8 [[NEGATE]], 7 +// CHECK: [[LOW:%[0-9]+]] = lshr i8 [[VALUE]], [[RSHIFT]] +// CHECK: [[RESULT:%[0-9]+]] = or i8 [[HIGH]], [[LOW]] // CHECK: ret i8 [[RESULT]] // CHECK } unsigned short test_rotl16(unsigned short value, unsigned char shift) { return _rotl16(value, shift); } // CHECK: i16 @test_rotl16 -// CHECK: [[SHIFT:%[0-9]+]] = and i16 %{{[0-9]+}}, 15 -// CHECK: [[NEGSHIFT:%[0-9]+]] = sub i16 16, [[SHIFT]] -// CHECK: [[HIGH:%[0-9]+]] = shl i16 [[VALUE:%[0-9]+]], [[SHIFT]] -// CHECK: [[LOW:%[0-9]+]] = lshr i16 [[VALUE]], [[NEGSHIFT]] -// CHECK: [[ROTATED:%[0-9]+]] = or i16 [[HIGH]], [[LOW]] -// CHECK: [[ISZERO:%[0-9]+]] = icmp eq i16 [[SHIFT]], 0 -// CHECK: [[RESULT:%[0-9]+]] = select i1 [[ISZERO]], i16 [[VALUE]], i16 [[ROTATED]]
[PATCH] D46737: Permit -fxray-instrument for NetBSD/amd64
This revision was automatically updated to reflect the committed changes. Closed by commit rC332070: Permit -fxray-instrument for NetBSD/amd64 (authored by kamil, committed by ). Herald added a subscriber: cfe-commits. Repository: rC Clang https://reviews.llvm.org/D46737 Files: lib/Driver/XRayArgs.cpp Index: lib/Driver/XRayArgs.cpp === --- lib/Driver/XRayArgs.cpp +++ lib/Driver/XRayArgs.cpp @@ -51,7 +51,8 @@ << (std::string(XRayInstrumentOption) + " on " + Triple.str()); } } else if (Triple.getOS() == llvm::Triple::FreeBSD || - Triple.getOS() == llvm::Triple::OpenBSD) { + Triple.getOS() == llvm::Triple::OpenBSD || + Triple.getOS() == llvm::Triple::NetBSD) { if (Triple.getArch() != llvm::Triple::x86_64) { D.Diag(diag::err_drv_clang_unsupported) << (std::string(XRayInstrumentOption) + " on " + Triple.str()); Index: lib/Driver/XRayArgs.cpp === --- lib/Driver/XRayArgs.cpp +++ lib/Driver/XRayArgs.cpp @@ -51,7 +51,8 @@ << (std::string(XRayInstrumentOption) + " on " + Triple.str()); } } else if (Triple.getOS() == llvm::Triple::FreeBSD || - Triple.getOS() == llvm::Triple::OpenBSD) { + Triple.getOS() == llvm::Triple::OpenBSD || + Triple.getOS() == llvm::Triple::NetBSD) { if (Triple.getArch() != llvm::Triple::x86_64) { D.Diag(diag::err_drv_clang_unsupported) << (std::string(XRayInstrumentOption) + " on " + Triple.str()); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46721: Support XRay in the NetBSD driver
This revision was automatically updated to reflect the committed changes. Closed by commit rC332071: Support XRay in the NetBSD driver (authored by kamil, committed by ). Herald added a subscriber: cfe-commits. Repository: rC Clang https://reviews.llvm.org/D46721 Files: lib/Driver/ToolChains/NetBSD.cpp Index: lib/Driver/ToolChains/NetBSD.cpp === --- lib/Driver/ToolChains/NetBSD.cpp +++ lib/Driver/ToolChains/NetBSD.cpp @@ -112,7 +112,9 @@ const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { - const Driver &D = getToolChain().getDriver(); + const toolchains::NetBSD &ToolChain = +static_cast(getToolChain()); + const Driver &D = ToolChain.getDriver(); ArgStringList CmdArgs; if (!D.SysRoot.empty()) @@ -135,15 +137,15 @@ // Many NetBSD architectures support more than one ABI. // Determine the correct emulation for ld. - switch (getToolChain().getArch()) { + switch (ToolChain.getArch()) { case llvm::Triple::x86: CmdArgs.push_back("-m"); CmdArgs.push_back("elf_i386"); break; case llvm::Triple::arm: case llvm::Triple::thumb: CmdArgs.push_back("-m"); -switch (getToolChain().getTriple().getEnvironment()) { +switch (ToolChain.getTriple().getEnvironment()) { case llvm::Triple::EABI: case llvm::Triple::GNUEABI: CmdArgs.push_back("armelf_nbsd_eabi"); @@ -159,9 +161,9 @@ break; case llvm::Triple::armeb: case llvm::Triple::thumbeb: -arm::appendEBLinkFlags(Args, CmdArgs, getToolChain().getEffectiveTriple()); +arm::appendEBLinkFlags(Args, CmdArgs, ToolChain.getEffectiveTriple()); CmdArgs.push_back("-m"); -switch (getToolChain().getTriple().getEnvironment()) { +switch (ToolChain.getTriple().getEnvironment()) { case llvm::Triple::EABI: case llvm::Triple::GNUEABI: CmdArgs.push_back("armelfb_nbsd_eabi"); @@ -179,13 +181,13 @@ case llvm::Triple::mips64el: if (mips::hasMipsAbiArg(Args, "32")) { CmdArgs.push_back("-m"); - if (getToolChain().getArch() == llvm::Triple::mips64) + if (ToolChain.getArch() == llvm::Triple::mips64) CmdArgs.push_back("elf32btsmip"); else CmdArgs.push_back("elf32ltsmip"); } else if (mips::hasMipsAbiArg(Args, "64")) { CmdArgs.push_back("-m"); - if (getToolChain().getArch() == llvm::Triple::mips64) + if (ToolChain.getArch() == llvm::Triple::mips64) CmdArgs.push_back("elf64btsmip"); else CmdArgs.push_back("elf64ltsmip"); @@ -226,16 +228,16 @@ if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { if (!Args.hasArg(options::OPT_shared)) { CmdArgs.push_back( - Args.MakeArgString(getToolChain().GetFilePath("crt0.o"))); + Args.MakeArgString(ToolChain.GetFilePath("crt0.o"))); } CmdArgs.push_back( -Args.MakeArgString(getToolChain().GetFilePath("crti.o"))); +Args.MakeArgString(ToolChain.GetFilePath("crti.o"))); if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie)) { CmdArgs.push_back( - Args.MakeArgString(getToolChain().GetFilePath("crtbeginS.o"))); + Args.MakeArgString(ToolChain.GetFilePath("crtbeginS.o"))); } else { CmdArgs.push_back( - Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o"))); + Args.MakeArgString(ToolChain.GetFilePath("crtbegin.o"))); } } @@ -248,13 +250,14 @@ Args.AddAllArgs(CmdArgs, options::OPT_r); bool NeedsSanitizerDeps = addSanitizerRuntimes(getToolChain(), Args, CmdArgs); + bool NeedsXRayDeps = addXRayRuntime(ToolChain, Args, CmdArgs); AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA); unsigned Major, Minor, Micro; - getToolChain().getTriple().getOSVersion(Major, Minor, Micro); + ToolChain.getTriple().getOSVersion(Major, Minor, Micro); bool useLibgcc = true; if (Major >= 7 || Major == 0) { -switch (getToolChain().getArch()) { +switch (ToolChain.getArch()) { case llvm::Triple::aarch64: case llvm::Triple::aarch64_be: case llvm::Triple::arm: @@ -278,12 +281,14 @@ if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { addOpenMPRuntime(CmdArgs, getToolChain(), Args); if (D.CCCIsCXX()) { - if (getToolChain().ShouldLinkCXXStdlib(Args)) -getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs); + if (ToolChain.ShouldLinkCXXStdlib(Args)) +ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs); CmdArgs.push_back("-lm"); } if (NeedsSanitizerDeps) linkSanitizerRuntimeDeps(getToolChain(), CmdArgs); +if (NeedsXRayDeps) + linkXRayRuntimeDeps(ToolChain, CmdArgs); if (Args.hasArg(options::OPT_pthread)) CmdArgs.push_back("-lpthread"); CmdArgs.push_back("-lc"); @@ -308,16 +313,1
[PATCH] D33844: [clang-tidy] terminating continue check
This revision was automatically updated to reflect the committed changes. Closed by commit rL332223: [clang-tidy] Add terminating continue check (authored by xazax, committed by ). Herald added subscribers: llvm-commits, klimek. Changed prior to commit: https://reviews.llvm.org/D33844?vs=142793&id=146566#toc Repository: rL LLVM https://reviews.llvm.org/D33844 Files: clang-tools-extra/trunk/clang-tidy/bugprone/BugproneTidyModule.cpp clang-tools-extra/trunk/clang-tidy/bugprone/CMakeLists.txt clang-tools-extra/trunk/clang-tidy/bugprone/TerminatingContinueCheck.cpp clang-tools-extra/trunk/clang-tidy/bugprone/TerminatingContinueCheck.h clang-tools-extra/trunk/docs/ReleaseNotes.rst clang-tools-extra/trunk/docs/clang-tidy/checks/bugprone-terminating-continue.rst clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst clang-tools-extra/trunk/test/clang-tidy/bugprone-terminating-continue.cpp Index: clang-tools-extra/trunk/test/clang-tidy/bugprone-terminating-continue.cpp === --- clang-tools-extra/trunk/test/clang-tidy/bugprone-terminating-continue.cpp +++ clang-tools-extra/trunk/test/clang-tidy/bugprone-terminating-continue.cpp @@ -0,0 +1,65 @@ +// RUN: %check_clang_tidy %s bugprone-terminating-continue %t + +void f() { + do { +continue; +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'continue' in loop with false condition is equivalent to 'break' [bugprone-terminating-continue] +// CHECK-FIXES: break; + } while(false); + + do { +continue; +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'continue' in loop with false condition is equivalent to 'break' [bugprone-terminating-continue] +// CHECK-FIXES: break; + } while(0); + + do { +continue; +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'continue' in loop with false condition is equivalent to 'break' [bugprone-terminating-continue] +// CHECK-FIXES: break; + } while(nullptr); + + do { +continue; +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'continue' in loop with false condition is equivalent to 'break' [bugprone-terminating-continue] +// CHECK-FIXES: break; + } while(__null); + + + do { +int x = 1; +if (x > 0) continue; +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'continue' in loop with false condition is equivalent to 'break' [bugprone-terminating-continue] +// CHECK-FIXES: if (x > 0) break; + } while (false); +} + +void g() { + do { +do { + continue; + int x = 1; +} while (1 == 1); + } while (false); + + do { +for (int i = 0; i < 1; ++i) { + continue; + int x = 1; +} + } while (false); + + do { +while (true) { + continue; + int x = 1; +} + } while (false); + + int v[] = {1,2,3,34}; + do { +for (int n : v) { + if (n>2) continue; +} + } while (false); +} Index: clang-tools-extra/trunk/clang-tidy/bugprone/TerminatingContinueCheck.cpp === --- clang-tools-extra/trunk/clang-tidy/bugprone/TerminatingContinueCheck.cpp +++ clang-tools-extra/trunk/clang-tidy/bugprone/TerminatingContinueCheck.cpp @@ -0,0 +1,49 @@ +//===--- TerminatingContinueCheck.cpp - clang-tidy-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include "TerminatingContinueCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" +#include "clang/Tooling/FixIt.h" + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace bugprone { + +void TerminatingContinueCheck::registerMatchers(MatchFinder *Finder) { + const auto doWithFalse = + doStmt(hasCondition(ignoringImpCasts( + anyOf(cxxBoolLiteral(equals(false)), integerLiteral(equals(0)), + cxxNullPtrLiteralExpr(), gnuNullExpr(, + equalsBoundNode("closestLoop")); + + Finder->addMatcher( + continueStmt(hasAncestor(stmt(anyOf(forStmt(), whileStmt(), + cxxForRangeStmt(), doStmt())) + .bind("closestLoop")), + hasAncestor(doWithFalse)) + .bind("continue"), + this); +} + +void TerminatingContinueCheck::check(const MatchFinder::MatchResult &Result) { + const auto *ContStmt = Result.Nodes.getNodeAs("continue"); + + auto Diag = + diag(ContStmt->getLocStart(), + "'continue' in loop with false condition is equivalent to 'break'") + << tooling::fixit::createReplacement(*ContStmt, "break"); +} + +} // namespace bugprone +} // namespace tidy +} // namespace clang Index: clang-tools-extra/trunk/clang-tidy/bugprone/BugproneTidyModule.cpp
[PATCH] D46795: [clangd] Don't query index when completing inside classes
This revision was automatically updated to reflect the committed changes. Closed by commit rCTE332226: [clangd] Don't query index when completing inside classes (authored by ibiryukov, committed by ). Changed prior to commit: https://reviews.llvm.org/D46795?vs=146571&id=146574#toc Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D46795 Files: clangd/CodeComplete.cpp unittests/clangd/CodeCompleteTests.cpp Index: unittests/clangd/CodeCompleteTests.cpp === --- unittests/clangd/CodeCompleteTests.cpp +++ unittests/clangd/CodeCompleteTests.cpp @@ -825,6 +825,67 @@ UnorderedElementsAre(""; } +TEST(CompletionTest, NoIndexCompletionsInsideClasses) { + auto Completions = completions( + R"cpp( +struct Foo { + int SomeNameOfField; + typedef int SomeNameOfTypedefField; +}; + +Foo::^)cpp", + {func("::SomeNameInTheIndex"), func("::Foo::SomeNameInTheIndex")}); + + EXPECT_THAT(Completions.items, + AllOf(Contains(Labeled("SomeNameOfField")), +Contains(Labeled("SomeNameOfTypedefField")), +Not(Contains(Labeled("SomeNameInTheIndex"); +} + +TEST(CompletionTest, NoIndexCompletionsInsideDependentCode) { + { +auto Completions = completions( +R"cpp( + template + void foo() { +T::^ + } + )cpp", +{func("::SomeNameInTheIndex")}); + +EXPECT_THAT(Completions.items, +Not(Contains(Labeled("SomeNameInTheIndex"; + } + + { +auto Completions = completions( +R"cpp( + template + void foo() { +T::template Y::^ + } + )cpp", +{func("::SomeNameInTheIndex")}); + +EXPECT_THAT(Completions.items, +Not(Contains(Labeled("SomeNameInTheIndex"; + } + + { +auto Completions = completions( +R"cpp( + template + void foo() { +T::foo::^ + } + )cpp", +{func("::SomeNameInTheIndex")}); + +EXPECT_THAT(Completions.items, +Not(Contains(Labeled("SomeNameInTheIndex"; + } +} + } // namespace } // namespace clangd } // namespace clang Index: clangd/CodeComplete.cpp === --- clangd/CodeComplete.cpp +++ clangd/CodeComplete.cpp @@ -759,9 +759,9 @@ return true; } -// Should we perform index-based completion in this context? +// Should we perform index-based completion in a context of the specified kind? // FIXME: consider allowing completion, but restricting the result types. -bool allowIndex(enum CodeCompletionContext::Kind K) { +bool contextAllowsIndex(enum CodeCompletionContext::Kind K) { switch (K) { case CodeCompletionContext::CCC_TopLevel: case CodeCompletionContext::CCC_ObjCInterface: @@ -803,6 +803,33 @@ llvm_unreachable("unknown code completion context"); } +// Should we allow index completions in the specified context? +bool allowIndex(CodeCompletionContext &CC) { + if (!contextAllowsIndex(CC.getKind())) +return false; + // We also avoid ClassName::bar (but allow namespace::bar). + auto Scope = CC.getCXXScopeSpecifier(); + if (!Scope) +return true; + NestedNameSpecifier *NameSpec = (*Scope)->getScopeRep(); + if (!NameSpec) +return true; + // We only query the index when qualifier is a namespace. + // If it's a class, we rely solely on sema completions. + switch (NameSpec->getKind()) { + case NestedNameSpecifier::Global: + case NestedNameSpecifier::Namespace: + case NestedNameSpecifier::NamespaceAlias: +return true; + case NestedNameSpecifier::Super: + case NestedNameSpecifier::TypeSpec: + case NestedNameSpecifier::TypeSpecWithTemplate: + // Unresolved inside a template. + case NestedNameSpecifier::Identifier: +return false; + } +} + } // namespace clang::CodeCompleteOptions CodeCompleteOptions::getClangCompleteOpts() const { @@ -918,7 +945,7 @@ } SymbolSlab queryIndex() { -if (!Opts.Index || !allowIndex(Recorder->CCContext.getKind())) +if (!Opts.Index || !allowIndex(Recorder->CCContext)) return SymbolSlab(); trace::Span Tracer("Query index"); SPAN_ATTACH(Tracer, "limit", Opts.Limit); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46639: [CodeComplete] Provide completion in decls even for incomplete types
This revision was automatically updated to reflect the committed changes. Closed by commit rL332244: [CodeComplete] Provide completion in decls even for incomplete types (authored by ibiryukov, committed by ). Herald added a subscriber: llvm-commits. Repository: rL LLVM https://reviews.llvm.org/D46639 Files: cfe/trunk/lib/Sema/SemaCodeComplete.cpp cfe/trunk/test/CodeCompletion/incomplete-ret-type.cpp Index: cfe/trunk/lib/Sema/SemaCodeComplete.cpp === --- cfe/trunk/lib/Sema/SemaCodeComplete.cpp +++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp @@ -4493,10 +4493,8 @@ return; // A complete type is needed to lookup for constructors. - if (!isCompleteType(Loc, Type)) -return; - - CXXRecordDecl *RD = Type->getAsCXXRecordDecl(); + CXXRecordDecl *RD = + isCompleteType(Loc, Type) ? Type->getAsCXXRecordDecl() : nullptr; if (!RD) { CodeCompleteExpression(S, Type); return; Index: cfe/trunk/test/CodeCompletion/incomplete-ret-type.cpp === --- cfe/trunk/test/CodeCompletion/incomplete-ret-type.cpp +++ cfe/trunk/test/CodeCompletion/incomplete-ret-type.cpp @@ -0,0 +1,13 @@ +struct IncompleteType; +int int_value; +typedef int int_typedef; + +void f(in); +IncompleteType g(in); +// Completing should produce results even if types are incomplete. +// Note that clang is expected to return an error code since 'in' does not resolve. +// RUN: not %clang_cc1 -fsyntax-only -code-completion-at=%s:5:9 %s -o - | FileCheck %s +// RUN: not %clang_cc1 -fsyntax-only -code-completion-at=%s:6:19 %s -o - | FileCheck %s +// CHECK: COMPLETION: int{{$}} +// CHECK: COMPLETION: int_typedef +// CHECK: COMPLETION: int_value Index: cfe/trunk/lib/Sema/SemaCodeComplete.cpp === --- cfe/trunk/lib/Sema/SemaCodeComplete.cpp +++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp @@ -4493,10 +4493,8 @@ return; // A complete type is needed to lookup for constructors. - if (!isCompleteType(Loc, Type)) -return; - - CXXRecordDecl *RD = Type->getAsCXXRecordDecl(); + CXXRecordDecl *RD = + isCompleteType(Loc, Type) ? Type->getAsCXXRecordDecl() : nullptr; if (!RD) { CodeCompleteExpression(S, Type); return; Index: cfe/trunk/test/CodeCompletion/incomplete-ret-type.cpp === --- cfe/trunk/test/CodeCompletion/incomplete-ret-type.cpp +++ cfe/trunk/test/CodeCompletion/incomplete-ret-type.cpp @@ -0,0 +1,13 @@ +struct IncompleteType; +int int_value; +typedef int int_typedef; + +void f(in); +IncompleteType g(in); +// Completing should produce results even if types are incomplete. +// Note that clang is expected to return an error code since 'in' does not resolve. +// RUN: not %clang_cc1 -fsyntax-only -code-completion-at=%s:5:9 %s -o - | FileCheck %s +// RUN: not %clang_cc1 -fsyntax-only -code-completion-at=%s:6:19 %s -o - | FileCheck %s +// CHECK: COMPLETION: int{{$}} +// CHECK: COMPLETION: int_typedef +// CHECK: COMPLETION: int_value ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46742: [X86] Use __builtin_convertvector to replace some of the avx512 truncate builtins.
This revision was automatically updated to reflect the committed changes. Closed by commit rC332266: [X86] Use __builtin_convertvector to replace some of the avx512 truncate… (authored by ctopper, committed by ). Changed prior to commit: https://reviews.llvm.org/D46742?vs=146286&id=146645#toc Repository: rC Clang https://reviews.llvm.org/D46742 Files: include/clang/Basic/BuiltinsX86.def lib/Headers/avx512bwintrin.h lib/Headers/avx512fintrin.h lib/Headers/avx512vlbwintrin.h lib/Headers/avx512vlintrin.h test/CodeGen/avx512bw-builtins.c test/CodeGen/avx512f-builtins.c test/CodeGen/avx512vl-builtins.c test/CodeGen/avx512vlbw-builtins.c Index: include/clang/Basic/BuiltinsX86.def === --- include/clang/Basic/BuiltinsX86.def +++ include/clang/Basic/BuiltinsX86.def @@ -1355,7 +1355,6 @@ TARGET_BUILTIN(__builtin_ia32_pmovswb512_mask, "V32cV32sV32cUi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_pmovuswb512_mask, "V32cV32sV32cUi", "nc", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_pmovwb512_mask, "V32cV32sV32cUi", "nc", "avx512bw") TARGET_BUILTIN(__builtin_ia32_cvtpd2qq128_mask, "V2LLiV2dV2LLiUc", "nc", "avx512vl,avx512dq") TARGET_BUILTIN(__builtin_ia32_cvtpd2qq256_mask, "V4LLiV4dV4LLiUc", "nc", "avx512vl,avx512dq") TARGET_BUILTIN(__builtin_ia32_cvtpd2uqq128_mask, "V2LLiV2dV2LLiUc", "nc", "avx512vl,avx512dq") @@ -1397,7 +1396,6 @@ TARGET_BUILTIN(__builtin_ia32_pmovuswb128_mask, "V16cV8sV16cUc", "nc", "avx512vl,avx512bw") TARGET_BUILTIN(__builtin_ia32_pmovuswb256_mask, "V16cV16sV16cUs", "nc", "avx512vl,avx512bw") TARGET_BUILTIN(__builtin_ia32_pmovwb128_mask, "V16cV8sV16cUc", "nc", "avx512vl,avx512bw") -TARGET_BUILTIN(__builtin_ia32_pmovwb256_mask, "V16cV16sV16cUs", "nc", "avx512vl,avx512bw") TARGET_BUILTIN(__builtin_ia32_cvtpd2qq512_mask, "V8LLiV8dV8LLiUcIi", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_cvtpd2uqq512_mask, "V8LLiV8dV8LLiUcIi", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_cvtps2qq512_mask, "V8LLiV8fV8LLiUcIi", "nc", "avx512dq") @@ -1719,16 +1717,12 @@ TARGET_BUILTIN(__builtin_ia32_pmovusqw128mem_mask, "vV8s*V2LLiUc", "n", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovusqw256_mask, "V8sV4LLiV8sUc", "nc", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovusqw256mem_mask, "vV8s*V4LLiUc", "n", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovdb512_mask, "V16cV16iV16cUs", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmovdb512mem_mask, "vV16c*V16iUs", "n", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmovwb512mem_mask, "vV32c*V32sUi", "n", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_pmovdw512_mask, "V16sV16iV16sUs", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmovdw512mem_mask, "vV16s*V16iUs", "n", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmovqb512_mask, "V16cV8LLiV16cUc", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmovqb512mem_mask, "vV16c*V8LLiUc", "n", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovqd512_mask, "V8iV8LLiV8iUc", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmovqd512mem_mask, "vV8i*V8LLiUc", "n", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pmovqw512_mask, "V8sV8LLiV8sUc", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmovqw512mem_mask, "vV8s*V8LLiUc", "n", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmovdb128_mask, "V16cV4iV16cUc", "nc", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovwb128mem_mask, "vV16c*V8sUc", "n", "avx512vl,avx512bw") @@ -1738,15 +1732,13 @@ TARGET_BUILTIN(__builtin_ia32_pmovwb256mem_mask, "vV16c*V16sUs", "n", "avx512vl,avx512bw") TARGET_BUILTIN(__builtin_ia32_pmovdw128_mask, "V8sV4iV8sUc", "nc", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovdw128mem_mask, "vV8s*V4iUc", "n", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovdw256_mask, "V8sV8iV8sUc", "nc", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovdw256mem_mask, "vV8s*V8iUc", "n", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovqb128_mask, "V16cV2LLiV16cUc", "nc", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovqb128mem_mask, "vV16c*V2LLiUc", "n", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovqb256_mask, "V16cV4LLiV16cUc", "nc", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovqb256mem_mask, "vV16c*V4LLiUc", "n", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovqd128_mask, "V4iV2LLiV4iUc", "nc", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovqd128mem_mask, "vV4i*V2LLiUc", "n", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pmovqd256_mask, "V4iV4LLiV4iUc", "nc", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovqd256mem_mask, "vV4i*V4LLiUc", "n", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovqw128_mask, "V8sV2LLiV8sUc", "nc", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovqw128mem_mask, "vV8s*V2LLiUc", "n", "avx512vl") Index: test/CodeGen/avx512bw-builtins.c === --- test/CodeGen/avx512bw-builtins.c +++ test/CodeGen/avx512bw-builtins.c @@ -1107,19 +1107,21 @@ __m256i test_mm512_cvtepi16_epi8(__m512i __A) { // CHECK-LABEL: @test_mm512_cvtepi16_e
[PATCH] D45177: CStringChecker, check strlcpy/strlcat
This revision was automatically updated to reflect the committed changes. Closed by commit rC332303: [analyzer] Re-apply r331096 "CStringChecker: Add support for BSD strlcpy()...". (authored by dergachev, committed by ). Repository: rC Clang https://reviews.llvm.org/D45177 Files: lib/StaticAnalyzer/Checkers/CStringChecker.cpp test/Analysis/bsd-string.c Index: test/Analysis/bsd-string.c === --- test/Analysis/bsd-string.c +++ test/Analysis/bsd-string.c @@ -0,0 +1,40 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s + +#define NULL ((void *)0) + +typedef __typeof(sizeof(int)) size_t; +size_t strlcpy(char *dst, const char *src, size_t n); +size_t strlcat(char *dst, const char *src, size_t n); +void clang_analyzer_eval(int); + +void f1() { + char overlap[] = "123456789"; + strlcpy(overlap, overlap + 1, 3); // expected-warning{{Arguments must not be overlapping buffers}} +} + +void f2() { + char buf[5]; + strlcpy(buf, "abcd", sizeof(buf)); // expected-no-warning + strlcat(buf, "efgh", sizeof(buf)); // expected-warning{{Size argument is greater than the free space in the destination buffer}} +} + +void f3() { + char dst[2]; + const char *src = "abdef"; + strlcpy(dst, src, 5); // expected-warning{{Size argument is greater than the length of the destination buffer}} +} + +void f4() { + strlcpy(NULL, "abcdef", 6); // expected-warning{{Null pointer argument in call to string copy function}} +} + +void f5() { + strlcat(NULL, "abcdef", 6); // expected-warning{{Null pointer argument in call to string copy function}} +} + +void f6() { + char buf[8]; + strlcpy(buf, "abc", 3); + size_t len = strlcat(buf, "defg", 4); + clang_analyzer_eval(len == 7); // expected-warning{{TRUE}} +} Index: lib/StaticAnalyzer/Checkers/CStringChecker.cpp === --- lib/StaticAnalyzer/Checkers/CStringChecker.cpp +++ lib/StaticAnalyzer/Checkers/CStringChecker.cpp @@ -97,14 +97,17 @@ void evalStrcpy(CheckerContext &C, const CallExpr *CE) const; void evalStrncpy(CheckerContext &C, const CallExpr *CE) const; void evalStpcpy(CheckerContext &C, const CallExpr *CE) const; + void evalStrlcpy(CheckerContext &C, const CallExpr *CE) const; void evalStrcpyCommon(CheckerContext &C, const CallExpr *CE, bool returnEnd, bool isBounded, -bool isAppending) const; +bool isAppending, +bool returnPtr = true) const; void evalStrcat(CheckerContext &C, const CallExpr *CE) const; void evalStrncat(CheckerContext &C, const CallExpr *CE) const; + void evalStrlcat(CheckerContext &C, const CallExpr *CE) const; void evalStrcmp(CheckerContext &C, const CallExpr *CE) const; void evalStrncmp(CheckerContext &C, const CallExpr *CE) const; @@ -1393,6 +1396,18 @@ /* isAppending = */ false); } +void CStringChecker::evalStrlcpy(CheckerContext &C, const CallExpr *CE) const { + if (CE->getNumArgs() < 3) +return; + + // char *strlcpy(char *dst, const char *src, size_t n); + evalStrcpyCommon(C, CE, + /* returnEnd = */ true, + /* isBounded = */ true, + /* isAppending = */ false, + /* returnPtr = */ false); +} + void CStringChecker::evalStrcat(CheckerContext &C, const CallExpr *CE) const { if (CE->getNumArgs() < 2) return; @@ -1415,9 +1430,21 @@ /* isAppending = */ true); } +void CStringChecker::evalStrlcat(CheckerContext &C, const CallExpr *CE) const { + if (CE->getNumArgs() < 3) +return; + + //char *strlcat(char *s1, const char *s2, size_t n); + evalStrcpyCommon(C, CE, + /* returnEnd = */ false, + /* isBounded = */ true, + /* isAppending = */ true, + /* returnPtr = */ false); +} + void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE, bool returnEnd, bool isBounded, - bool isAppending) const { + bool isAppending, bool returnPtr) const { CurrentFunctionDescription = "string copy function"; ProgramStateRef state = C.getState(); const LocationContext *LCtx = C.getLocationContext(); @@ -1455,6 +1482,11 @@ SVal maxLastElementIndex = UnknownVal(); const char *boundWarning = nullptr; + state = CheckOverlap(C, state, isBounded ? CE->getArg(2) : CE->getArg(1), Dst, srcExpr); + + if (!state) +return; + // If the function is strncpy, strncat, etc... it is bounded. if (isBounded) { // Get the max number of characters to copy. @@ -1658,35 +1690,41 @@ finalStrLength = amountCopied; } - // The final result o
[PATCH] D44975: Change DEBUG() macro to LLVM_DEBUG()
This revision was automatically updated to reflect the committed changes. Closed by commit rL332350: [clang] Update uses of DEBUG macro to LLVM_DEBUG. (authored by nzaghen, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D44975?vs=140055&id=146806#toc Repository: rL LLVM https://reviews.llvm.org/D44975 Files: cfe/trunk/lib/AST/ExprConstant.cpp cfe/trunk/lib/Analysis/BodyFarm.cpp cfe/trunk/lib/CodeGen/ObjectFilePCHContainerOperations.cpp cfe/trunk/lib/Format/BreakableToken.cpp cfe/trunk/lib/Format/ContinuationIndenter.cpp cfe/trunk/lib/Format/Format.cpp cfe/trunk/lib/Format/SortJavaScriptImports.cpp cfe/trunk/lib/Format/TokenAnalyzer.cpp cfe/trunk/lib/Format/TokenAnnotator.cpp cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp cfe/trunk/lib/Format/UnwrappedLineParser.cpp cfe/trunk/lib/Format/UsingDeclarationsSorter.cpp cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp cfe/trunk/lib/StaticAnalyzer/Core/MemRegion.cpp cfe/trunk/lib/Tooling/Tooling.cpp cfe/trunk/unittests/Format/FormatTest.cpp cfe/trunk/unittests/Format/FormatTestComments.cpp cfe/trunk/unittests/Format/FormatTestJS.cpp cfe/trunk/unittests/Format/FormatTestJava.cpp cfe/trunk/unittests/Format/FormatTestObjC.cpp cfe/trunk/unittests/Format/FormatTestProto.cpp cfe/trunk/unittests/Format/FormatTestRawStrings.cpp cfe/trunk/unittests/Format/FormatTestSelective.cpp cfe/trunk/unittests/Format/FormatTestTextProto.cpp cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp cfe/trunk/unittests/Format/UsingDeclarationsSorterTest.cpp cfe/trunk/unittests/libclang/LibclangTest.cpp Index: cfe/trunk/lib/Tooling/Tooling.cpp === --- cfe/trunk/lib/Tooling/Tooling.cpp +++ cfe/trunk/lib/Tooling/Tooling.cpp @@ -473,7 +473,7 @@ // FIXME: We need a callback mechanism for the tool writer to output a // customized message for each file. - DEBUG({ llvm::dbgs() << "Processing: " << File << ".\n"; }); + LLVM_DEBUG({ llvm::dbgs() << "Processing: " << File << ".\n"; }); ToolInvocation Invocation(std::move(CommandLine), Action, Files.get(), PCHContainerOps); Invocation.setDiagnosticConsumer(DiagConsumer); Index: cfe/trunk/lib/CodeGen/ObjectFilePCHContainerOperations.cpp === --- cfe/trunk/lib/CodeGen/ObjectFilePCHContainerOperations.cpp +++ cfe/trunk/lib/CodeGen/ObjectFilePCHContainerOperations.cpp @@ -290,7 +290,7 @@ else ASTSym->setSection("__clangast"); -DEBUG({ +LLVM_DEBUG({ // Print the IR for the PCH container to the debug output. llvm::SmallString<0> Buffer; clang::EmitBackendOutput( Index: cfe/trunk/lib/StaticAnalyzer/Core/MemRegion.cpp === --- cfe/trunk/lib/StaticAnalyzer/Core/MemRegion.cpp +++ cfe/trunk/lib/StaticAnalyzer/Core/MemRegion.cpp @@ -1244,8 +1244,8 @@ if (!Overflow) Overflow = checkedMul(Mult, offset.getQuantity()); if (Overflow) { - DEBUG(llvm::dbgs() << "MemRegion::getAsArrayOffset: " - << "offset overflowing, returning unknown\n"); + LLVM_DEBUG(llvm::dbgs() << "MemRegion::getAsArrayOffset: " + << "offset overflowing, returning unknown\n"); return nullptr; } Index: cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp === --- cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp +++ cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp @@ -399,10 +399,10 @@ getManager()->getContext(FD); bool IsAutosynthesized; Stmt* Body = AD->getBody(IsAutosynthesized); - DEBUG({ - if (IsAutosynthesized) -llvm::dbgs() << "Using autosynthesized body for " << FD->getName() - << "\n"; + LLVM_DEBUG({ +if (IsAutosynthesized) + llvm::dbgs() << "Using autosynthesized body for " << FD->getName() + << "\n"; }); if (Body) { const Decl* Decl = AD->getDecl(); Index: cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp === --- cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp +++ cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp @@ -905,7 +905,8 @@ Penalty = Queue.top().first.first; StateNode *Node = Queue.top().second; if (!Node->State.NextToken) { -DEBUG(llvm::dbgs() << "\n---\nPenalty for line: " << Penalty << "\n"); +LLVM_DEBUG(llvm::dbgs() + << "\n---\nPenalty for line: " << Penalty << "\n"); break; } Queue.pop(); @@ -929,16 +930,17 @@ if (Queue.empty()) { // We were unable to find a solution, do nothing. // FIXME: Add diagnostic? - DEBUG(llvm::dbgs
[PATCH] D44976: Change DEBUG() macro to LLVM_DEBUG() in clang-tools-extra
This revision was automatically updated to reflect the committed changes. Closed by commit rL332371: [clang-tools-extra] Update uses of DEBUG macro to LLVM_DEBUG. (authored by nzaghen, committed by ). Herald added subscribers: llvm-commits, klimek. Changed prior to commit: https://reviews.llvm.org/D44976?vs=140056&id=146860#toc Repository: rL LLVM https://reviews.llvm.org/D44976 Files: clang-tools-extra/trunk/clang-move/ClangMove.cpp clang-tools-extra/trunk/clang-move/HelperDeclRefGraph.cpp clang-tools-extra/trunk/clang-tidy/ClangTidyOptions.cpp clang-tools-extra/trunk/clang-tidy/readability/IdentifierNamingCheck.cpp clang-tools-extra/trunk/include-fixer/IncludeFixer.cpp clang-tools-extra/trunk/include-fixer/SymbolIndexManager.cpp Index: clang-tools-extra/trunk/include-fixer/SymbolIndexManager.cpp === --- clang-tools-extra/trunk/include-fixer/SymbolIndexManager.cpp +++ clang-tools-extra/trunk/include-fixer/SymbolIndexManager.cpp @@ -97,8 +97,8 @@ Symbols.insert(Symbols.end(), Res.begin(), Res.end()); } -DEBUG(llvm::dbgs() << "Searching " << Names.back() << "... got " - << Symbols.size() << " results...\n"); +LLVM_DEBUG(llvm::dbgs() << "Searching " << Names.back() << "... got " +<< Symbols.size() << " results...\n"); for (auto &SymAndSig : Symbols) { const SymbolInfo &Symbol = SymAndSig.Symbol; Index: clang-tools-extra/trunk/include-fixer/IncludeFixer.cpp === --- clang-tools-extra/trunk/include-fixer/IncludeFixer.cpp +++ clang-tools-extra/trunk/include-fixer/IncludeFixer.cpp @@ -156,7 +156,8 @@ clang::ASTContext &context = CI->getASTContext(); std::string QueryString = QualType(T->getUnqualifiedDesugaredType(), 0) .getAsString(context.getPrintingPolicy()); - DEBUG(llvm::dbgs() << "Query missing complete type '" << QueryString << "'"); + LLVM_DEBUG(llvm::dbgs() << "Query missing complete type '" << QueryString + << "'"); // Pass an empty range here since we don't add qualifier in this case. std::vector MatchedSymbols = query(QueryString, "", tooling::Range()); @@ -276,7 +277,8 @@ SymbolRange = CreateToolingRange(Typo.getLoc()); } - DEBUG(llvm::dbgs() << "TypoScopeQualifiers: " << TypoScopeString << "\n"); + LLVM_DEBUG(llvm::dbgs() << "TypoScopeQualifiers: " << TypoScopeString + << "\n"); std::vector MatchedSymbols = query(QueryString, TypoScopeString, SymbolRange); @@ -357,12 +359,12 @@ return {}; } - DEBUG(llvm::dbgs() << "Looking up '" << Query << "' at "); - DEBUG(CI->getSourceManager() -.getLocForStartOfFile(CI->getSourceManager().getMainFileID()) -.getLocWithOffset(Range.getOffset()) -.print(llvm::dbgs(), CI->getSourceManager())); - DEBUG(llvm::dbgs() << " ..."); + LLVM_DEBUG(llvm::dbgs() << "Looking up '" << Query << "' at "); + LLVM_DEBUG(CI->getSourceManager() + .getLocForStartOfFile(CI->getSourceManager().getMainFileID()) + .getLocWithOffset(Range.getOffset()) + .print(llvm::dbgs(), CI->getSourceManager())); + LLVM_DEBUG(llvm::dbgs() << " ..."); llvm::StringRef FileName = CI->getSourceManager().getFilename( CI->getSourceManager().getLocForStartOfFile( CI->getSourceManager().getMainFileID())); @@ -390,8 +392,8 @@ if (MatchedSymbols.empty()) MatchedSymbols = SymbolIndexMgr.search(Query, /*IsNestedSearch=*/true, FileName); - DEBUG(llvm::dbgs() << "Having found " << MatchedSymbols.size() - << " symbols\n"); + LLVM_DEBUG(llvm::dbgs() << "Having found " << MatchedSymbols.size() + << " symbols\n"); // We store a copy of MatchedSymbols in a place where it's globally reachable. // This is used by the standalone version of the tool. this->MatchedSymbols = MatchedSymbols; Index: clang-tools-extra/trunk/clang-tidy/ClangTidyOptions.cpp === --- clang-tools-extra/trunk/clang-tidy/ClangTidyOptions.cpp +++ clang-tools-extra/trunk/clang-tidy/ClangTidyOptions.cpp @@ -225,7 +225,8 @@ // similar. std::vector FileOptionsProvider::getRawOptions(StringRef FileName) { - DEBUG(llvm::dbgs() << "Getting options for file " << FileName << "...\n"); + LLVM_DEBUG(llvm::dbgs() << "Getting options for file " << FileName + << "...\n"); assert(FS && "FS must be set."); llvm::SmallString<128> AbsoluteFilePath(FileName); @@ -254,8 +255,8 @@ if (Result) { // Store cached value for all intermediate directories. while (Path != CurrentPath) { -DEBUG(llvm::dbgs() << "Caching configuration for path " << Path - << ".\n"); +LLVM_DEBUG(ll
[PATCH] D46836: Fix some rtti-options tests
This revision was automatically updated to reflect the committed changes. Closed by commit rC332384: Fixed some rtti-options tests. (authored by ssrivastava, committed by ). Changed prior to commit: https://reviews.llvm.org/D46836?vs=146632&id=146893#toc Repository: rC Clang https://reviews.llvm.org/D46836 Files: test/Driver/rtti-options.cpp Index: test/Driver/rtti-options.cpp === --- test/Driver/rtti-options.cpp +++ test/Driver/rtti-options.cpp @@ -5,8 +5,8 @@ // Special cases: -fcxx-exceptions in C code should warn about unused arguments // We should also not have any rtti-related arguments -// RUN: %clang -x c -### -target x86_64-scei-ps4 -c -fcxx-exceptions %s 2>&1 | FileCheck -check-prefix=CHECK-UNUSED -check-prefix=CHECK-RTTI -check-prefix=CHECK-NO-RTTI %s -// RUN: %clang -x c -### -target x86_64-unknown-unknown -c -fcxx-exceptions %s 2>&1 | FileCheck -check-prefix=CHECK-UNUSED -check-prefix=CHECK-RTTI -check-prefix=CHECK-NO-RTTI %s +// RUN: %clang -x c -### -target x86_64-scei-ps4 -c -fcxx-exceptions %s 2>&1 | FileCheck -check-prefix=CHECK-UNUSED -check-prefix=CHECK-RTTI %s +// RUN: %clang -x c -### -target x86_64-unknown-unknown -c -fcxx-exceptions %s 2>&1 | FileCheck -check-prefix=CHECK-UNUSED -check-prefix=CHECK-RTTI %s // Make sure we keep the last -frtti/-fno-rtti argument // RUN: %clang -### -c -fno-rtti -frtti %s 2>&1 | FileCheck -check-prefix=CHECK-RTTI %s @@ -56,6 +56,6 @@ // CHECK-EXC-ERROR: invalid argument '-fno-rtti' not allowed with '-fexceptions' // CHECK-EXC-ERROR-CXX: invalid argument '-fno-rtti' not allowed with '-fcxx-exceptions' // CHECK-RTTI-NOT: "-fno-rtti" -// CHECK-NO-RTTI-NOT: "-frtti" +// CHECK-NO-RTTI: "-fno-rtti" // CHECK-OK-NOT: {{warning:|error:}} Index: test/Driver/rtti-options.cpp === --- test/Driver/rtti-options.cpp +++ test/Driver/rtti-options.cpp @@ -5,8 +5,8 @@ // Special cases: -fcxx-exceptions in C code should warn about unused arguments // We should also not have any rtti-related arguments -// RUN: %clang -x c -### -target x86_64-scei-ps4 -c -fcxx-exceptions %s 2>&1 | FileCheck -check-prefix=CHECK-UNUSED -check-prefix=CHECK-RTTI -check-prefix=CHECK-NO-RTTI %s -// RUN: %clang -x c -### -target x86_64-unknown-unknown -c -fcxx-exceptions %s 2>&1 | FileCheck -check-prefix=CHECK-UNUSED -check-prefix=CHECK-RTTI -check-prefix=CHECK-NO-RTTI %s +// RUN: %clang -x c -### -target x86_64-scei-ps4 -c -fcxx-exceptions %s 2>&1 | FileCheck -check-prefix=CHECK-UNUSED -check-prefix=CHECK-RTTI %s +// RUN: %clang -x c -### -target x86_64-unknown-unknown -c -fcxx-exceptions %s 2>&1 | FileCheck -check-prefix=CHECK-UNUSED -check-prefix=CHECK-RTTI %s // Make sure we keep the last -frtti/-fno-rtti argument // RUN: %clang -### -c -fno-rtti -frtti %s 2>&1 | FileCheck -check-prefix=CHECK-RTTI %s @@ -56,6 +56,6 @@ // CHECK-EXC-ERROR: invalid argument '-fno-rtti' not allowed with '-fexceptions' // CHECK-EXC-ERROR-CXX: invalid argument '-fno-rtti' not allowed with '-fcxx-exceptions' // CHECK-RTTI-NOT: "-fno-rtti" -// CHECK-NO-RTTI-NOT: "-frtti" +// CHECK-NO-RTTI: "-fno-rtti" // CHECK-OK-NOT: {{warning:|error:}} ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D41968: [libunwind][MIPS] Support MIPS floating-point registers for hard-float ABIs.
This revision was automatically updated to reflect the committed changes. Closed by commit rL332414: [libunwind][MIPS] Support MIPS floating-point registers for hard-float ABIs. (authored by jhb, committed by ). Herald added a subscriber: llvm-commits. Repository: rL LLVM https://reviews.llvm.org/D41968 Files: libunwind/trunk/include/__libunwind_config.h libunwind/trunk/include/libunwind.h libunwind/trunk/src/Registers.hpp libunwind/trunk/src/UnwindRegistersRestore.S libunwind/trunk/src/UnwindRegistersSave.S libunwind/trunk/src/libunwind.cpp Index: libunwind/trunk/src/Registers.hpp === --- libunwind/trunk/src/Registers.hpp +++ libunwind/trunk/src/Registers.hpp @@ -2718,6 +2718,14 @@ }; mips_o32_thread_state_t _registers; +#ifdef __mips_hard_float + /// O32 with 32-bit floating point registers only uses half of this + /// space. However, using the same layout for 32-bit vs 64-bit + /// floating point registers results in a single context size for + /// O32 with hard float. + uint32_t _padding; + double _floats[32]; +#endif }; inline Registers_mips_o32::Registers_mips_o32(const void *registers) { @@ -2744,13 +2752,28 @@ return true; if (regNum == UNW_MIPS_LO) return true; - // FIXME: Hard float, DSP accumulator registers, MSA registers +#if defined(__mips_hard_float) && __mips_fpr == 32 + if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) +return true; +#endif + // FIXME: DSP accumulator registers, MSA registers return false; } inline uint32_t Registers_mips_o32::getRegister(int regNum) const { if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) return _registers.__r[regNum - UNW_MIPS_R0]; +#if defined(__mips_hard_float) && __mips_fpr == 32 + if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) { +uint32_t *p; + +if (regNum % 2 == 0) + p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0]; +else + p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1; +return *p; + } +#endif switch (regNum) { case UNW_REG_IP: @@ -2770,6 +2793,18 @@ _registers.__r[regNum - UNW_MIPS_R0] = value; return; } +#if defined(__mips_hard_float) && __mips_fpr == 32 + if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) { +uint32_t *p; + +if (regNum % 2 == 0) + p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0]; +else + p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1; +*p = value; +return; + } +#endif switch (regNum) { case UNW_REG_IP: @@ -2788,17 +2823,31 @@ _LIBUNWIND_ABORT("unsupported mips_o32 register"); } -inline bool Registers_mips_o32::validFloatRegister(int /* regNum */) const { +inline bool Registers_mips_o32::validFloatRegister(int regNum) const { +#if defined(__mips_hard_float) && __mips_fpr == 64 + if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) +return true; +#endif return false; } -inline double Registers_mips_o32::getFloatRegister(int /* regNum */) const { +inline double Registers_mips_o32::getFloatRegister(int regNum) const { +#if defined(__mips_hard_float) && __mips_fpr == 64 + assert(validFloatRegister(regNum)); + return _floats[regNum - UNW_MIPS_F0]; +#else _LIBUNWIND_ABORT("mips_o32 float support not implemented"); +#endif } -inline void Registers_mips_o32::setFloatRegister(int /* regNum */, - double /* value */) { +inline void Registers_mips_o32::setFloatRegister(int regNum, + double value) { +#if defined(__mips_hard_float) && __mips_fpr == 64 + assert(validFloatRegister(regNum)); + _floats[regNum - UNW_MIPS_F0] = value; +#else _LIBUNWIND_ABORT("mips_o32 float support not implemented"); +#endif } inline bool Registers_mips_o32::validVectorRegister(int /* regNum */) const { @@ -2879,6 +2928,70 @@ return "$30"; case UNW_MIPS_R31: return "$31"; + case UNW_MIPS_F0: +return "$f0"; + case UNW_MIPS_F1: +return "$f1"; + case UNW_MIPS_F2: +return "$f2"; + case UNW_MIPS_F3: +return "$f3"; + case UNW_MIPS_F4: +return "$f4"; + case UNW_MIPS_F5: +return "$f5"; + case UNW_MIPS_F6: +return "$f6"; + case UNW_MIPS_F7: +return "$f7"; + case UNW_MIPS_F8: +return "$f8"; + case UNW_MIPS_F9: +return "$f9"; + case UNW_MIPS_F10: +return "$f10"; + case UNW_MIPS_F11: +return "$f11"; + case UNW_MIPS_F12: +return "$f12"; + case UNW_MIPS_F13: +return "$f13"; + case UNW_MIPS_F14: +return "$f14"; + case UNW_MIPS_F15: +return "$f15"; + case UNW_MIPS_F16: +return "$f16"; + case UNW_MIPS_F17: +return "$f17"; + case UNW_MIPS_F18: +return "$f18"; + case UNW_MIPS_F19: +return "$f19"; + case UNW_MIPS_F20: +return "$f20"; + case UNW_MIPS_F21: +return "$f21"; + case UNW_MIPS_F22: +return "$f22"; + case UNW_MIPS_F23: +return "$f23"; + case UNW_MIPS_F24: +return
[PATCH] D46902: [analyzer] Make plist-html multi-file.
This revision was automatically updated to reflect the committed changes. Closed by commit rL332417: [analyzer] Make plist-html diagnostic consumer produce multi-file reports. (authored by dergachev, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D46902?vs=146902&id=146966#toc Repository: rL LLVM https://reviews.llvm.org/D46902 Files: cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp cfe/trunk/test/Analysis/diagnostics/plist-multi-file.c cfe/trunk/test/Analysis/diagnostics/plist-multi-file.h Index: cfe/trunk/test/Analysis/diagnostics/plist-multi-file.c === --- cfe/trunk/test/Analysis/diagnostics/plist-multi-file.c +++ cfe/trunk/test/Analysis/diagnostics/plist-multi-file.c @@ -0,0 +1,205 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=plist-html -o %t.plist -verify %s +// RUN: FileCheck --input-file=%t.plist %s + +#include "plist-multi-file.h" + +void bar() { + foo(0); +} + +// CHECK: diagnostics +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: path +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: kindevent +// CHECK-NEXT: location +// CHECK-NEXT: +// CHECK-NEXT: line7 +// CHECK-NEXT: col7 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: ranges +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line7 +// CHECK-NEXT: col7 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line7 +// CHECK-NEXT: col7 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: depth0 +// CHECK-NEXT: extended_message +// CHECK-NEXT: Passing null pointer value via 1st parameter 'ptr' +// CHECK-NEXT: message +// CHECK-NEXT: Passing null pointer value via 1st parameter 'ptr' +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: kindevent +// CHECK-NEXT: location +// CHECK-NEXT: +// CHECK-NEXT: line7 +// CHECK-NEXT: col3 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: ranges +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line7 +// CHECK-NEXT: col3 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line7 +// CHECK-NEXT: col8 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: depth0 +// CHECK-NEXT: extended_message +// CHECK-NEXT: Calling 'foo' +// CHECK-NEXT: message +// CHECK-NEXT: Calling 'foo' +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: kindevent +// CHECK-NEXT: location +// CHECK-NEXT: +// CHECK-NEXT: line1 +// CHECK-NEXT: col1 +// CHECK-NEXT: file1 +// CHECK-NEXT: +// CHECK-NEXT: depth1 +// CHECK-NEXT: extended_message +// CHECK-NEXT: Entered call from 'bar' +// CHECK-NEXT: message +// CHECK-NEXT: Entered call from 'bar' +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: kindcontrol +// CHECK-NEXT: edges +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT:start +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line1 +// CHECK-NEXT: col1 +// CHECK-NEXT: file1 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line1 +// CHECK-NEXT: col4 +// CHECK-NEXT: file1 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT:end +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line2 +// CHECK-NEXT: col3 +// CHECK-NEXT: file1 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line2 +// CHECK-NEXT: col3 +// CHECK-NEXT: file1 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: kindcontrol +// CHECK-NEXT: edges +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT:start +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line2 +// CHECK-NEXT: col3 +// CHECK-NEXT: file1 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line2 +// CHECK-NEXT: col3 +// CHECK-NEXT: file1 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT:end +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line2 +// CHECK-NEXT: col8 +// CHECK-NEXT: file1 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line2 +// CHECK-NEXT: col8 +// CHECK-NEXT: file1 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +//
[PATCH] D46001: [CodeComplete] Expose helpers to get RawComment of completion result.
This revision was automatically updated to reflect the committed changes. Closed by commit rC332457: [CodeComplete] Expose helpers to get RawComment of completion result. (authored by ibiryukov, committed by ). Changed prior to commit: https://reviews.llvm.org/D46001?vs=146812&id=147061#toc Repository: rC Clang https://reviews.llvm.org/D46001 Files: include/clang/Sema/CodeCompleteConsumer.h lib/Sema/SemaCodeComplete.cpp Index: include/clang/Sema/CodeCompleteConsumer.h === --- include/clang/Sema/CodeCompleteConsumer.h +++ include/clang/Sema/CodeCompleteConsumer.h @@ -46,6 +46,7 @@ class NestedNameSpecifier; class Preprocessor; class Sema; +class RawComment; /// Default priority values for code-completion results based /// on their kind. @@ -1073,6 +1074,23 @@ virtual CodeCompletionTUInfo &getCodeCompletionTUInfo() = 0; }; +/// Get the documentation comment used to produce +/// CodeCompletionString::BriefComment for RK_Declaration. +const RawComment *getCompletionComment(const ASTContext &Ctx, + const NamedDecl *Decl); + +/// Get the documentation comment used to produce +/// CodeCompletionString::BriefComment for RK_Pattern. +const RawComment *getPatternCompletionComment(const ASTContext &Ctx, + const NamedDecl *Decl); + +/// Get the documentation comment used to produce +/// CodeCompletionString::BriefComment for OverloadCandidate. +const RawComment * +getParameterComment(const ASTContext &Ctx, +const CodeCompleteConsumer::OverloadCandidate &Result, +unsigned ArgIndex); + /// A simple code-completion consumer that prints the results it /// receives in a simple format. class PrintingCodeCompleteConsumer : public CodeCompleteConsumer { Index: lib/Sema/SemaCodeComplete.cpp === --- lib/Sema/SemaCodeComplete.cpp +++ lib/Sema/SemaCodeComplete.cpp @@ -2765,27 +2765,11 @@ if (Declaration) { Result.addParentContext(Declaration->getDeclContext()); Pattern->ParentName = Result.getParentName(); - // Provide code completion comment for self.GetterName where - // GetterName is the getter method for a property with name - // different from the property name (declared via a property - // getter attribute. - const NamedDecl *ND = Declaration; - if (const ObjCMethodDecl *M = dyn_cast(ND)) -if (M->isPropertyAccessor()) - if (const ObjCPropertyDecl *PDecl = M->findPropertyDecl()) -if (PDecl->getGetterName() == M->getSelector() && -PDecl->getIdentifier() != M->getIdentifier()) { - if (const RawComment *RC = -Ctx.getRawCommentForAnyRedecl(M)) { -Result.addBriefComment(RC->getBriefText(Ctx)); -Pattern->BriefComment = Result.getBriefComment(); - } - else if (const RawComment *RC = - Ctx.getRawCommentForAnyRedecl(PDecl)) { -Result.addBriefComment(RC->getBriefText(Ctx)); -Pattern->BriefComment = Result.getBriefComment(); - } -} + if (const RawComment *RC = + getPatternCompletionComment(Ctx, Declaration)) { +Result.addBriefComment(RC->getBriefText(Ctx)); +Pattern->BriefComment = Result.getBriefComment(); + } } return Pattern; @@ -2845,14 +2829,9 @@ if (IncludeBriefComments) { // Add documentation comment, if it exists. -if (const RawComment *RC = Ctx.getRawCommentForAnyRedecl(ND)) { +if (const RawComment *RC = getCompletionComment(Ctx, Declaration)) { Result.addBriefComment(RC->getBriefText(Ctx)); } -else if (const ObjCMethodDecl *OMD = dyn_cast(ND)) - if (OMD->isPropertyAccessor()) -if (const ObjCPropertyDecl *PDecl = OMD->findPropertyDecl()) - if (const RawComment *RC = Ctx.getRawCommentForAnyRedecl(PDecl)) -Result.addBriefComment(RC->getBriefText(Ctx)); } if (StartsNestedNameSpecifier) { @@ -3042,6 +3021,59 @@ return Result.TakeString(); } +const RawComment *clang::getCompletionComment(const ASTContext &Ctx, + const NamedDecl *ND) { + if (!ND) +return nullptr; + if (auto *RC = Ctx.getRawCommentForAnyRedecl(ND)) +return RC; + + // Try to find comment from a property for ObjC methods. + const ObjCMethodDecl *M = dyn_cast(ND); + if (!M) +return nullptr; + const ObjCPropertyDecl *PDecl = M->findPropertyDecl(); + if (!PDecl) +return nullptr; + + return Ctx.getRawCommentForAnyRedecl(PDecl); +} + +const RawComment *clang::getPatternCompletionComment(const ASTContext &Ctx, + const NamedDecl *ND) { + const ObjCMethodDecl *M = dyn_cast_or_null(ND
[PATCH] D46000: [AST] Added a helper to extract a user-friendly text of a comment.
This revision was automatically updated to reflect the committed changes. Closed by commit rL332458: [AST] Added a helper to extract a user-friendly text of a comment. (authored by ibiryukov, committed by ). Herald added a subscriber: llvm-commits. Repository: rL LLVM https://reviews.llvm.org/D46000 Files: cfe/trunk/include/clang/AST/CommentLexer.h cfe/trunk/include/clang/AST/RawCommentList.h cfe/trunk/lib/AST/CommentLexer.cpp cfe/trunk/lib/AST/RawCommentList.cpp cfe/trunk/unittests/AST/CMakeLists.txt cfe/trunk/unittests/AST/CommentTextTest.cpp Index: cfe/trunk/include/clang/AST/CommentLexer.h === --- cfe/trunk/include/clang/AST/CommentLexer.h +++ cfe/trunk/include/clang/AST/CommentLexer.h @@ -281,6 +281,11 @@ /// command, including command marker. SmallString<16> VerbatimBlockEndCommandName; + /// If true, the commands, html tags, etc will be parsed and reported as + /// separate tokens inside the comment body. If false, the comment text will + /// be parsed into text and newline tokens. + bool ParseCommands; + /// Given a character reference name (e.g., "lt"), return the character that /// it stands for (e.g., "<"). StringRef resolveHTMLNamedCharacterReference(StringRef Name) const; @@ -315,12 +320,11 @@ /// Eat string matching regexp \code \s*\* \endcode. void skipLineStartingDecorations(); - /// Lex stuff inside comments. CommentEnd should be set correctly. + /// Lex comment text, including commands if ParseCommands is set to true. void lexCommentText(Token &T); - void setupAndLexVerbatimBlock(Token &T, -const char *TextBegin, -char Marker, const CommandInfo *Info); + void setupAndLexVerbatimBlock(Token &T, const char *TextBegin, char Marker, +const CommandInfo *Info); void lexVerbatimBlockFirstLine(Token &T); @@ -343,14 +347,13 @@ public: Lexer(llvm::BumpPtrAllocator &Allocator, DiagnosticsEngine &Diags, -const CommandTraits &Traits, -SourceLocation FileLoc, -const char *BufferStart, const char *BufferEnd); +const CommandTraits &Traits, SourceLocation FileLoc, +const char *BufferStart, const char *BufferEnd, +bool ParseCommands = true); void lex(Token &T); - StringRef getSpelling(const Token &Tok, -const SourceManager &SourceMgr, + StringRef getSpelling(const Token &Tok, const SourceManager &SourceMgr, bool *Invalid = nullptr) const; }; Index: cfe/trunk/include/clang/AST/RawCommentList.h === --- cfe/trunk/include/clang/AST/RawCommentList.h +++ cfe/trunk/include/clang/AST/RawCommentList.h @@ -111,6 +111,30 @@ return extractBriefText(Context); } + /// Returns sanitized comment text, suitable for presentation in editor UIs. + /// E.g. will transform: + /// // This is a long multiline comment. + /// // Parts of it might be indented. + /// /* The comments styles might be mixed. */ + /// into + /// "This is a long multiline comment.\n" + /// " Parts of it might be indented.\n" + /// "The comments styles might be mixed." + /// Also removes leading indentation and sanitizes some common cases: + /// /* This is a first line. + /// * This is a second line. It is indented. + /// * This is a third line. */ + /// and + /// /* This is a first line. + /// This is a second line. It is indented. + /// This is a third line. */ + /// will both turn into: + /// "This is a first line.\n" + /// " This is a second line. It is indented.\n" + /// "This is a third line." + std::string getFormattedText(const SourceManager &SourceMgr, + DiagnosticsEngine &Diags) const; + /// Parse the comment, assuming it is attached to decl \c D. comments::FullComment *parse(const ASTContext &Context, const Preprocessor *PP, const Decl *D) const; Index: cfe/trunk/lib/AST/CommentLexer.cpp === --- cfe/trunk/lib/AST/CommentLexer.cpp +++ cfe/trunk/lib/AST/CommentLexer.cpp @@ -294,6 +294,39 @@ assert(CommentState == LCS_InsideBCPLComment || CommentState == LCS_InsideCComment); + // Handles lexing non-command text, i.e. text and newline. + auto HandleNonCommandToken = [&]() -> void { +assert(State == LS_Normal); + +const char *TokenPtr = BufferPtr; +assert(TokenPtr < CommentEnd); +switch (*TokenPtr) { + case '\n': + case '\r': + TokenPtr = skipNewline(TokenPtr, CommentEnd); + formTokenWithChars(T, TokenPtr, tok::newline); + + if (CommentState == LCS_InsideCComment) +skipLineStartingDecorations(); + return; + + default: { +
[PATCH] D46002: [clangd] Parse all comments in Sema and completion.
This revision was automatically updated to reflect the committed changes. Closed by commit rCTE332460: [clangd] Parse all comments in Sema and completion. (authored by ibiryukov, committed by ). Changed prior to commit: https://reviews.llvm.org/D46002?vs=146831&id=147064#toc Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D46002 Files: clangd/ClangdUnit.cpp clangd/CodeComplete.cpp unittests/clangd/CodeCompleteTests.cpp Index: unittests/clangd/CodeCompleteTests.cpp === --- unittests/clangd/CodeCompleteTests.cpp +++ unittests/clangd/CodeCompleteTests.cpp @@ -628,6 +628,30 @@ Doc("Doooc"), Detail("void"; } +TEST(CompletionTest, Documentation) { + auto Results = completions( + R"cpp( + // Non-doxygen comment. + int foo(); + /// Doxygen comment. + /// \param int a + int bar(int a); + /* Multi-line + block comment + */ + int baz(); + + int x = ^ + )cpp"); + EXPECT_THAT(Results.items, + Contains(AllOf(Named("foo"), Doc("Non-doxygen comment."; + EXPECT_THAT( + Results.items, + Contains(AllOf(Named("bar"), Doc("Doxygen comment.\n\\param int a"; + EXPECT_THAT(Results.items, + Contains(AllOf(Named("baz"), Doc("Multi-line\nblock comment"; +} + TEST(CodeCompleteTest, DisableTypoCorrection) { auto Results = completions(R"cpp( namespace clang { int v; } Index: clangd/ClangdUnit.cpp === --- clangd/ClangdUnit.cpp +++ clangd/ClangdUnit.cpp @@ -25,6 +25,7 @@ #include "clang/Sema/Sema.h" #include "clang/Serialization/ASTWriter.h" #include "clang/Tooling/CompilationDatabase.h" +#include "clang/Basic/LangOptions.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/CrashRecoveryContext.h" @@ -316,6 +317,7 @@ } // createInvocationFromCommandLine sets DisableFree. CI->getFrontendOpts().DisableFree = false; +CI->getLangOpts()->CommentOpts.ParseAllComments = true; } std::unique_ptr ContentsBuffer = Index: clangd/CodeComplete.cpp === --- clangd/CodeComplete.cpp +++ clangd/CodeComplete.cpp @@ -25,6 +25,7 @@ #include "Trace.h" #include "URI.h" #include "index/Index.h" +#include "clang/Basic/LangOptions.h" #include "clang/Format/Format.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendActions.h" @@ -648,6 +649,7 @@ return false; } CI->getFrontendOpts().DisableFree = false; + CI->getLangOpts()->CommentOpts.ParseAllComments = true; std::unique_ptr ContentsBuffer = llvm::MemoryBuffer::getMemBufferCopy(Input.Contents, Input.FileName); Index: unittests/clangd/CodeCompleteTests.cpp === --- unittests/clangd/CodeCompleteTests.cpp +++ unittests/clangd/CodeCompleteTests.cpp @@ -628,6 +628,30 @@ Doc("Doooc"), Detail("void"; } +TEST(CompletionTest, Documentation) { + auto Results = completions( + R"cpp( + // Non-doxygen comment. + int foo(); + /// Doxygen comment. + /// \param int a + int bar(int a); + /* Multi-line + block comment + */ + int baz(); + + int x = ^ + )cpp"); + EXPECT_THAT(Results.items, + Contains(AllOf(Named("foo"), Doc("Non-doxygen comment."; + EXPECT_THAT( + Results.items, + Contains(AllOf(Named("bar"), Doc("Doxygen comment.\n\\param int a"; + EXPECT_THAT(Results.items, + Contains(AllOf(Named("baz"), Doc("Multi-line\nblock comment"; +} + TEST(CodeCompleteTest, DisableTypoCorrection) { auto Results = completions(R"cpp( namespace clang { int v; } Index: clangd/ClangdUnit.cpp === --- clangd/ClangdUnit.cpp +++ clangd/ClangdUnit.cpp @@ -25,6 +25,7 @@ #include "clang/Sema/Sema.h" #include "clang/Serialization/ASTWriter.h" #include "clang/Tooling/CompilationDatabase.h" +#include "clang/Basic/LangOptions.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/CrashRecoveryContext.h" @@ -316,6 +317,7 @@ } // createInvocationFromCommandLine sets DisableFree. CI->getFrontendOpts().DisableFree = false; +CI->getLangOpts()->CommentOpts.ParseAllComments = true; } std::unique_ptr ContentsBuffer = Index: clangd/CodeComplete.cpp === --- clangd/CodeComplete.cpp +++ clangd/CodeComplete.cpp @@ -25,6 +25,7 @@ #include "Trace.h" #include "URI.h" #include "index/Index.h" +#include "clang/Basic/LangOptions.h" #include "clang/Format/Format.h" #include "clang/Frontend/CompilerInstance.h" #include "clang
[PATCH] D45999: [clangd] Retrieve minimally formatted comment text in completion.
This revision was automatically updated to reflect the committed changes. Closed by commit rCTE332459: [clangd] Retrieve minimally formatted comment text in completion. (authored by ibiryukov, committed by ). Changed prior to commit: https://reviews.llvm.org/D45999?vs=147060&id=147063#toc Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D45999 Files: clangd/CodeComplete.cpp clangd/CodeComplete.h clangd/CodeCompletionStrings.cpp clangd/CodeCompletionStrings.h clangd/index/SymbolCollector.cpp unittests/clangd/CodeCompleteTests.cpp unittests/clangd/CodeCompletionStringsTests.cpp unittests/clangd/SymbolCollectorTests.cpp Index: unittests/clangd/CodeCompletionStringsTests.cpp === --- unittests/clangd/CodeCompletionStringsTests.cpp +++ unittests/clangd/CodeCompletionStringsTests.cpp @@ -51,23 +51,24 @@ } TEST_F(CompletionStringTest, Documentation) { - Builder.addBriefComment("Is this brief?"); - EXPECT_EQ(getDocumentation(*Builder.TakeString()), "Is this brief?"); + Builder.addBriefComment("This is ignored"); + EXPECT_EQ(formatDocumentation(*Builder.TakeString(), "Is this brief?"), +"Is this brief?"); } TEST_F(CompletionStringTest, DocumentationWithAnnotation) { - Builder.addBriefComment("Is this brief?"); + Builder.addBriefComment("This is ignored"); Builder.AddAnnotation("Ano"); - EXPECT_EQ(getDocumentation(*Builder.TakeString()), + EXPECT_EQ(formatDocumentation(*Builder.TakeString(), "Is this brief?"), "Annotation: Ano\n\nIs this brief?"); } TEST_F(CompletionStringTest, MultipleAnnotations) { Builder.AddAnnotation("Ano1"); Builder.AddAnnotation("Ano2"); Builder.AddAnnotation("Ano3"); - EXPECT_EQ(getDocumentation(*Builder.TakeString()), + EXPECT_EQ(formatDocumentation(*Builder.TakeString(), ""), "Annotations: Ano1 Ano2 Ano3\n"); } @@ -97,7 +98,7 @@ TEST_F(CompletionStringTest, FunctionSnippet) { Builder.AddResultTypeChunk("result no no"); - Builder.addBriefComment("Foo's comment"); + Builder.addBriefComment("This comment is ignored"); Builder.AddTypedTextChunk("Foo"); Builder.AddChunk(CodeCompletionString::CK_LeftParen); Builder.AddPlaceholderChunk("p1"); @@ -113,7 +114,7 @@ labelAndInsertText(*CCS, /*EnableSnippets=*/true); EXPECT_EQ(Label, "Foo(p1, p2)"); EXPECT_EQ(InsertText, "Foo(${1:p1}, ${2:p2})"); - EXPECT_EQ(getDocumentation(*CCS), "Foo's comment"); + EXPECT_EQ(formatDocumentation(*CCS, "Foo's comment"), "Foo's comment"); EXPECT_EQ(getFilterText(*CCS), "Foo"); } Index: unittests/clangd/SymbolCollectorTests.cpp === --- unittests/clangd/SymbolCollectorTests.cpp +++ unittests/clangd/SymbolCollectorTests.cpp @@ -490,11 +490,11 @@ } )"; runSymbolCollector(Header, /*Main=*/""); - EXPECT_THAT(Symbols, - UnorderedElementsAre(QName("nx"), - AllOf(QName("nx::ff"), - Labeled("ff(int x, double y)"), - Detail("int"), Doc("Foo comment."; + EXPECT_THAT( + Symbols, + UnorderedElementsAre( + QName("nx"), AllOf(QName("nx::ff"), Labeled("ff(int x, double y)"), + Detail("int"), Doc("Foo comment."; } TEST_F(SymbolCollectorTest, PlainAndSnippet) { Index: unittests/clangd/CodeCompleteTests.cpp === --- unittests/clangd/CodeCompleteTests.cpp +++ unittests/clangd/CodeCompleteTests.cpp @@ -261,8 +261,7 @@ // completion. At least there aren't any we're aware of. EXPECT_THAT(Results.items, Not(Contains(Kind(CompletionItemKind::Snippet; // Check documentation. - EXPECT_IFF(Opts.IncludeBriefComments, Results.items, - Contains(IsDocumented())); + EXPECT_IFF(Opts.IncludeComments, Results.items, Contains(IsDocumented())); } void TestGlobalScopeCompletion(clangd::CodeCompleteOptions Opts) { @@ -307,8 +306,7 @@ AllOf(Has("local_var"), Has("LocalClass"), Contains(Kind(CompletionItemKind::Snippet; // Check documentation. - EXPECT_IFF(Opts.IncludeBriefComments, Results.items, - Contains(IsDocumented())); + EXPECT_IFF(Opts.IncludeComments, Results.items, Contains(IsDocumented())); } TEST(CompletionTest, CompletionOptions) { @@ -319,7 +317,7 @@ // We used to test every combination of options, but that got too slow (2^N). auto Flags = { &clangd::CodeCompleteOptions::IncludeMacros, - &clangd::CodeCompleteOptions::IncludeBriefComments, + &clangd::CodeCompleteOptions::IncludeComments, &clangd::CodeCompleteOptions::EnableSnippets, &clangd::CodeCompleteOptions::IncludeCodePatterns, &clangd::CodeCompleteOptions::IncludeIneligibleResults, Index: clangd/index/SymbolCollector.cpp ==
[PATCH] D44934: [analyzer] Improve the modeling of `memset()`.
This revision was automatically updated to reflect the committed changes. Closed by commit rL332463: [analyzer] Improve the modeling of memset(). (authored by henrywong, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D44934?vs=146816&id=147066#toc Repository: rL LLVM https://reviews.llvm.org/D44934 Files: cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp cfe/trunk/test/Analysis/bstring.cpp cfe/trunk/test/Analysis/null-deref-ps-region.c cfe/trunk/test/Analysis/string.c Index: cfe/trunk/test/Analysis/bstring.cpp === --- cfe/trunk/test/Analysis/bstring.cpp +++ cfe/trunk/test/Analysis/bstring.cpp @@ -1,7 +1,8 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s -// RUN: %clang_analyze_cc1 -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s -// RUN: %clang_analyze_cc1 -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s -// RUN: %clang_analyze_cc1 -DUSE_BUILTINS -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.cstring,unix.Malloc,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s +// RUN: %clang_analyze_cc1 -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,unix.Malloc,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s +// RUN: %clang_analyze_cc1 -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,unix.Malloc,debug.ExprInspection -analyzer-store=region -verify %s +// RUN: %clang_analyze_cc1 -DUSE_BUILTINS -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,unix.Malloc,debug.ExprInspection -analyzer-store=region -verify %s +// RUN: %clang_analyze_cc1 -DSUPPRESS_OUT_OF_BOUND -analyzer-checker=core,unix.cstring,unix.Malloc,alpha.unix.cstring.BufferOverlap,alpha.unix.cstring.NotNullTerminated,debug.ExprInspection -analyzer-store=region -verify %s #include "Inputs/system-header-simulator-cxx.h" #include "Inputs/system-header-simulator-for-malloc.h" @@ -77,3 +78,118 @@ unsigned *f; }; } + +void *memset(void *dest, int ch, std::size_t count); +namespace memset_non_pod { +class Base { +public: + int b_mem; + Base() : b_mem(1) {} +}; + +class Derived : public Base { +public: + int d_mem; + Derived() : d_mem(2) {} +}; + +void memset1_inheritance() { + Derived d; + memset(&d, 0, sizeof(Derived)); + clang_analyzer_eval(d.b_mem == 0); // expected-warning{{TRUE}} + clang_analyzer_eval(d.d_mem == 0); // expected-warning{{TRUE}} +} + +#ifdef SUPPRESS_OUT_OF_BOUND +void memset2_inheritance_field() { + Derived d; + memset(&d.d_mem, 0, sizeof(Derived)); + clang_analyzer_eval(d.b_mem == 0); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(d.d_mem == 0); // expected-warning{{UNKNOWN}} +} + +void memset3_inheritance_field() { + Derived d; + memset(&d.b_mem, 0, sizeof(Derived)); + clang_analyzer_eval(d.b_mem == 0); // expected-warning{{TRUE}} + clang_analyzer_eval(d.d_mem == 0); // expected-warning{{TRUE}} +} +#endif + +void memset4_array_nonpod_object() { + Derived array[10]; + clang_analyzer_eval(array[1].b_mem == 1); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(array[1].d_mem == 2); // expected-warning{{UNKNOWN}} + memset(&array[1], 0, sizeof(Derived)); + clang_analyzer_eval(array[1].b_mem == 0); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(array[1].d_mem == 0); // expected-warning{{UNKNOWN}} +} + +void memset5_array_nonpod_object() { + Derived array[10]; + clang_analyzer_eval(array[1].b_mem == 1); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(array[1].d_mem == 2); // expected-warning{{UNKNOWN}} + memset(array, 0, sizeof(array)); + clang_analyzer_eval(array[1].b_mem == 0); // expected-warning{{TRUE}} + clang_analyzer_eval(array[1].d_mem == 0); // expected-warning{{TRUE}} +} + +void memset6_new_array_nonpod_object() { + Derived *array = new Derived[10]; + clang_analyzer_eval(array[2].b_mem == 1); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(array[2].d_mem == 2); // expected-warning{{UNKNOWN}} + memset(array, 0, 10 * sizeof(Derived)); + clang_analyzer_eval(array[2].b_mem == 0); // expected-warning{{TRUE}} + clang_analyzer_eval(array[2].d_mem == 0); // expected-warning{{TRUE}} + delete[] array; +} + +void memset7_placement_new() { + Derived *d = new Derived(); + clang_analyzer_eval(d->b_mem == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(d->d_mem == 2); // expected-warning{{TRUE}} + + memset(d, 0, sizeof(Derived)); + clang_analyzer_eval(d->b_mem == 0); // expected-warning{{TRUE}} + clang_analyzer_eval(d->d_mem == 0); // expected-warning{{TRUE}} + + Derived *d1 = new (d) Deriv
[PATCH] D46936: [Timers] TimerGroup::printJSONValues(): print mem timer with .mem suffix
This revision was automatically updated to reflect the committed changes. Closed by commit rL332503: [Timers] TimerGroup::printJSONValues(): print mem timer with .mem suffix (authored by lebedevri, committed by ). Changed prior to commit: https://reviews.llvm.org/D46936?vs=147052&id=147137#toc Repository: rL LLVM https://reviews.llvm.org/D46936 Files: llvm/trunk/lib/Support/Timer.cpp Index: llvm/trunk/lib/Support/Timer.cpp === --- llvm/trunk/lib/Support/Timer.cpp +++ llvm/trunk/lib/Support/Timer.cpp @@ -387,7 +387,7 @@ printJSONValue(OS, R, ".sys", T.getSystemTime()); if (T.getMemUsed()) { OS << delim; - printJSONValue(OS, R, ".sys", T.getMemUsed()); + printJSONValue(OS, R, ".mem", T.getMemUsed()); } } TimersToPrint.clear(); Index: llvm/trunk/lib/Support/Timer.cpp === --- llvm/trunk/lib/Support/Timer.cpp +++ llvm/trunk/lib/Support/Timer.cpp @@ -387,7 +387,7 @@ printJSONValue(OS, R, ".sys", T.getSystemTime()); if (T.getMemUsed()) { OS << delim; - printJSONValue(OS, R, ".sys", T.getMemUsed()); + printJSONValue(OS, R, ".mem", T.getMemUsed()); } } TimersToPrint.clear(); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46937: [Timers] TimerGroup::printJSONValue(): print doubles with no precision loss
This revision was automatically updated to reflect the committed changes. Closed by commit rL332504: [Timers] TimerGroup::printJSONValue(): print doubles with no precision loss (authored by lebedevri, committed by ). Changed prior to commit: https://reviews.llvm.org/D46937?vs=147053&id=147138#toc Repository: rL LLVM https://reviews.llvm.org/D46937 Files: llvm/trunk/lib/Support/Timer.cpp Index: llvm/trunk/lib/Support/Timer.cpp === --- llvm/trunk/lib/Support/Timer.cpp +++ llvm/trunk/lib/Support/Timer.cpp @@ -22,6 +22,8 @@ #include "llvm/Support/Process.h" #include "llvm/Support/YAMLTraits.h" #include "llvm/Support/raw_ostream.h" +#include + using namespace llvm; // This ugly hack is brought to you courtesy of constructor/destructor ordering @@ -367,10 +369,12 @@ void TimerGroup::printJSONValue(raw_ostream &OS, const PrintRecord &R, const char *suffix, double Value) { assert(yaml::needsQuotes(Name) == yaml::QuotingType::None && - "TimerGroup name needs no quotes"); + "TimerGroup name should not need quotes"); assert(yaml::needsQuotes(R.Name) == yaml::QuotingType::None && - "Timer name needs no quotes"); - OS << "\t\"time." << Name << '.' << R.Name << suffix << "\": " << Value; + "Timer name should not need quotes"); + constexpr auto max_digits10 = std::numeric_limits::max_digits10; + OS << "\t\"time." << Name << '.' << R.Name << suffix + << "\": " << format("%.*e", max_digits10 - 1, Value); } const char *TimerGroup::printJSONValues(raw_ostream &OS, const char *delim) { Index: llvm/trunk/lib/Support/Timer.cpp === --- llvm/trunk/lib/Support/Timer.cpp +++ llvm/trunk/lib/Support/Timer.cpp @@ -22,6 +22,8 @@ #include "llvm/Support/Process.h" #include "llvm/Support/YAMLTraits.h" #include "llvm/Support/raw_ostream.h" +#include + using namespace llvm; // This ugly hack is brought to you courtesy of constructor/destructor ordering @@ -367,10 +369,12 @@ void TimerGroup::printJSONValue(raw_ostream &OS, const PrintRecord &R, const char *suffix, double Value) { assert(yaml::needsQuotes(Name) == yaml::QuotingType::None && - "TimerGroup name needs no quotes"); + "TimerGroup name should not need quotes"); assert(yaml::needsQuotes(R.Name) == yaml::QuotingType::None && - "Timer name needs no quotes"); - OS << "\t\"time." << Name << '.' << R.Name << suffix << "\": " << Value; + "Timer name should not need quotes"); + constexpr auto max_digits10 = std::numeric_limits::max_digits10; + OS << "\t\"time." << Name << '.' << R.Name << suffix + << "\": " << format("%.*e", max_digits10 - 1, Value); } const char *TimerGroup::printJSONValues(raw_ostream &OS, const char *delim) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46938: [Timers] TimerGroup: make printJSONValues() method public
This revision was automatically updated to reflect the committed changes. Closed by commit rL332505: [Timers] TimerGroup: make printJSONValues() method public (authored by lebedevri, committed by ). Changed prior to commit: https://reviews.llvm.org/D46938?vs=147054&id=147139#toc Repository: rL LLVM https://reviews.llvm.org/D46938 Files: llvm/trunk/include/llvm/Support/Timer.h llvm/trunk/lib/Support/Timer.cpp Index: llvm/trunk/lib/Support/Timer.cpp === --- llvm/trunk/lib/Support/Timer.cpp +++ llvm/trunk/lib/Support/Timer.cpp @@ -378,6 +378,8 @@ } const char *TimerGroup::printJSONValues(raw_ostream &OS, const char *delim) { + sys::SmartScopedLock L(*TimerLock); + prepareToPrintList(); for (const PrintRecord &R : TimersToPrint) { OS << delim; Index: llvm/trunk/include/llvm/Support/Timer.h === --- llvm/trunk/include/llvm/Support/Timer.h +++ llvm/trunk/include/llvm/Support/Timer.h @@ -207,6 +207,8 @@ /// This static method prints all timers and clears them all out. static void printAll(raw_ostream &OS); + const char *printJSONValues(raw_ostream &OS, const char *delim); + /// Prints all timers as JSON key/value pairs, and clears them all out. static const char *printAllJSONValues(raw_ostream &OS, const char *delim); @@ -223,7 +225,6 @@ void PrintQueuedTimers(raw_ostream &OS); void printJSONValue(raw_ostream &OS, const PrintRecord &R, const char *suffix, double Value); - const char *printJSONValues(raw_ostream &OS, const char *delim); }; } // end namespace llvm Index: llvm/trunk/lib/Support/Timer.cpp === --- llvm/trunk/lib/Support/Timer.cpp +++ llvm/trunk/lib/Support/Timer.cpp @@ -378,6 +378,8 @@ } const char *TimerGroup::printJSONValues(raw_ostream &OS, const char *delim) { + sys::SmartScopedLock L(*TimerLock); + prepareToPrintList(); for (const PrintRecord &R : TimersToPrint) { OS << delim; Index: llvm/trunk/include/llvm/Support/Timer.h === --- llvm/trunk/include/llvm/Support/Timer.h +++ llvm/trunk/include/llvm/Support/Timer.h @@ -207,6 +207,8 @@ /// This static method prints all timers and clears them all out. static void printAll(raw_ostream &OS); + const char *printJSONValues(raw_ostream &OS, const char *delim); + /// Prints all timers as JSON key/value pairs, and clears them all out. static const char *printAllJSONValues(raw_ostream &OS, const char *delim); @@ -223,7 +225,6 @@ void PrintQueuedTimers(raw_ostream &OS); void printJSONValue(raw_ostream &OS, const PrintRecord &R, const char *suffix, double Value); - const char *printJSONValues(raw_ostream &OS, const char *delim); }; } // end namespace llvm ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46939: [Timers] TimerGroup: add constructor from StringMap
This revision was automatically updated to reflect the committed changes. Closed by commit rL332506: [Timers] TimerGroup: add constructor from StringMap(authored by lebedevri, committed by ). Changed prior to commit: https://reviews.llvm.org/D46939?vs=147055&id=147140#toc Repository: rL LLVM https://reviews.llvm.org/D46939 Files: llvm/trunk/include/llvm/Support/Timer.h llvm/trunk/lib/Support/Timer.cpp Index: llvm/trunk/include/llvm/Support/Timer.h === --- llvm/trunk/include/llvm/Support/Timer.h +++ llvm/trunk/include/llvm/Support/Timer.h @@ -10,6 +10,7 @@ #ifndef LLVM_SUPPORT_TIMER_H #define LLVM_SUPPORT_TIMER_H +#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/DataTypes.h" #include @@ -194,6 +195,10 @@ public: explicit TimerGroup(StringRef Name, StringRef Description); + + explicit TimerGroup(StringRef Name, StringRef Description, + const StringMap &Records); + ~TimerGroup(); void setName(StringRef NewName, StringRef NewDescription) { Index: llvm/trunk/lib/Support/Timer.cpp === --- llvm/trunk/lib/Support/Timer.cpp +++ llvm/trunk/lib/Support/Timer.cpp @@ -236,6 +236,15 @@ TimerGroupList = this; } +TimerGroup::TimerGroup(StringRef Name, StringRef Description, + const StringMap &Records) +: TimerGroup(Name, Description) { + TimersToPrint.reserve(Records.size()); + for (const auto &P : Records) +TimersToPrint.emplace_back(P.getValue(), P.getKey(), P.getKey()); + assert(TimersToPrint.size() == Records.size() && "Size mismatch"); +} + TimerGroup::~TimerGroup() { // If the timer group is destroyed before the timers it owns, accumulate and // print the timing data. Index: llvm/trunk/include/llvm/Support/Timer.h === --- llvm/trunk/include/llvm/Support/Timer.h +++ llvm/trunk/include/llvm/Support/Timer.h @@ -10,6 +10,7 @@ #ifndef LLVM_SUPPORT_TIMER_H #define LLVM_SUPPORT_TIMER_H +#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/DataTypes.h" #include @@ -194,6 +195,10 @@ public: explicit TimerGroup(StringRef Name, StringRef Description); + + explicit TimerGroup(StringRef Name, StringRef Description, + const StringMap &Records); + ~TimerGroup(); void setName(StringRef NewName, StringRef NewDescription) { Index: llvm/trunk/lib/Support/Timer.cpp === --- llvm/trunk/lib/Support/Timer.cpp +++ llvm/trunk/lib/Support/Timer.cpp @@ -236,6 +236,15 @@ TimerGroupList = this; } +TimerGroup::TimerGroup(StringRef Name, StringRef Description, + const StringMap &Records) +: TimerGroup(Name, Description) { + TimersToPrint.reserve(Records.size()); + for (const auto &P : Records) +TimersToPrint.emplace_back(P.getValue(), P.getKey(), P.getKey()); + assert(TimersToPrint.size() == Records.size() && "Size mismatch"); +} + TimerGroup::~TimerGroup() { // If the timer group is destroyed before the timers it owns, accumulate and // print the timing data. ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46982: Do not enable RTTI with -fexceptions, for PS4
This revision was automatically updated to reflect the committed changes. Closed by commit rL332784: Do not enable RTTI with -fexceptions, for PS4 (authored by ssrivastava, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D46982?vs=147196&id=147616#toc Repository: rL LLVM https://reviews.llvm.org/D46982 Files: cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td cfe/trunk/include/clang/Driver/ToolChain.h cfe/trunk/lib/Driver/SanitizerArgs.cpp cfe/trunk/lib/Driver/ToolChain.cpp cfe/trunk/lib/Driver/ToolChains/Clang.cpp cfe/trunk/test/Driver/rtti-options.cpp Index: cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td === --- cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td +++ cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td @@ -266,9 +266,6 @@ InGroup>; def warn_debug_compression_unavailable : Warning<"cannot compress debug sections (zlib not installed)">, InGroup>; -def warn_drv_enabling_rtti_with_exceptions : Warning< - "implicitly enabling rtti for exception handling">, - InGroup>; def warn_drv_disabling_vptr_no_rtti_default : Warning< "implicitly disabling vptr sanitizer because rtti wasn't enabled">, InGroup; Index: cfe/trunk/include/clang/Driver/ToolChain.h === --- cfe/trunk/include/clang/Driver/ToolChain.h +++ cfe/trunk/include/clang/Driver/ToolChain.h @@ -100,10 +100,8 @@ }; enum RTTIMode { -RM_EnabledExplicitly, -RM_EnabledImplicitly, -RM_DisabledExplicitly, -RM_DisabledImplicitly +RM_Enabled, +RM_Disabled, }; private: Index: cfe/trunk/test/Driver/rtti-options.cpp === --- cfe/trunk/test/Driver/rtti-options.cpp +++ cfe/trunk/test/Driver/rtti-options.cpp @@ -1,11 +1,11 @@ // Check that we emit warnings/errors for different combinations of -// exceptions, rtti, and vptr sanitizer flags when targeting the PS4. +// exceptions, rtti, and vptr sanitizer flags for generic (unknown) x86 linux, +// and for PS4 when its behaviour differs from the generic x86-linux. // No warnings/errors should be emitted for unknown, except if combining // the vptr sanitizer with -fno-rtti // Special cases: -fcxx-exceptions in C code should warn about unused arguments // We should also not have any rtti-related arguments -// RUN: %clang -x c -### -target x86_64-scei-ps4 -c -fcxx-exceptions %s 2>&1 | FileCheck -check-prefix=CHECK-UNUSED -check-prefix=CHECK-RTTI %s // RUN: %clang -x c -### -target x86_64-unknown-unknown -c -fcxx-exceptions %s 2>&1 | FileCheck -check-prefix=CHECK-UNUSED -check-prefix=CHECK-RTTI %s // Make sure we keep the last -frtti/-fno-rtti argument @@ -22,39 +22,26 @@ // RUN: %clang -### -c -target x86_64-unknown-linux -fsanitize=undefined %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s // RUN: %clang -### -c -target x86_64-unknown-linux -fsanitize=undefined -frtti %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s // RUN: %clang -### -c -target x86_64-scei-ps4 -fsanitize=vptr %s 2>&1 | FileCheck -check-prefix=CHECK-SAN-WARN %s -// RUN: %clang -### -c -target x86_64-scei-ps4 -fsanitize=vptr -frtti %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s -// RUN: %clang -### -c -target x86_64-scei-ps4 -fsanitize=vptr -fno-rtti %s 2>&1 | FileCheck -check-prefix=CHECK-SAN-ERROR %s -// RUN: %clang -### -c -target x86_64-scei-ps4 -fsanitize=undefined -frtti %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s // Exceptions + no/default rtti -// RUN: %clang -### -c -target x86_64-scei-ps4 -fcxx-exceptions -fno-rtti %s 2>&1 | FileCheck -check-prefix=CHECK-EXC-ERROR-CXX %s -// RUN: %clang -### -c -target x86_64-scei-ps4 -fcxx-exceptions %s 2>&1 | FileCheck -check-prefix=CHECK-EXC-WARN %s // RUN: %clang -### -c -target x86_64-unknown-unknown -fcxx-exceptions -fno-rtti %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s // RUN: %clang -### -c -target x86_64-unknown-unknown -fcxx-exceptions %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s // In C++, -fexceptions implies -fcxx-exceptions -// RUN: %clang -x c++ -### -c -target x86_64-scei-ps4 -fexceptions -fno-rtti %s 2>&1 | FileCheck -check-prefix=CHECK-EXC-ERROR %s -// RUN: %clang -x c++ -### -c -target x86_64-scei-ps4 -fexceptions %s 2>&1 | FileCheck -check-prefix=CHECK-EXC-WARN %s // RUN: %clang -x c++ -### -c -target x86_64-unknown-unknown -fexceptions -fno-rtti %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s // RUN: %clang -x c++ -### -c -target x86_64-unknown-unknown -fexceptions %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s // -frtti + exceptions -// RUN: %clang -### -c -target x86_64-scei-ps4 -fcxx-exceptions -frtti %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s // RUN: %clang -### -c -target x86_64-unknown-unknown -fcxx-exceptions -frtti %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s // -f{no-,}rtti/default -// RUN: %clang -### -c -ta
[PATCH] D41785: Print the qualified name when dumping deserialized decls.
This revision was automatically updated to reflect the committed changes. Closed by commit rL332817: Print the qualified name when dumping deserialized decls. (authored by vvassilev, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D41785?vs=128791&id=147706#toc Repository: rL LLVM https://reviews.llvm.org/D41785 Files: cfe/trunk/lib/Frontend/FrontendAction.cpp Index: cfe/trunk/lib/Frontend/FrontendAction.cpp === --- cfe/trunk/lib/Frontend/FrontendAction.cpp +++ cfe/trunk/lib/Frontend/FrontendAction.cpp @@ -88,8 +88,10 @@ void DeclRead(serialization::DeclID ID, const Decl *D) override { llvm::outs() << "PCH DECL: " << D->getDeclKindName(); -if (const NamedDecl *ND = dyn_cast(D)) - llvm::outs() << " - " << *ND; +if (const NamedDecl *ND = dyn_cast(D)) { + llvm::outs() << " - "; + ND->printQualifiedName(llvm::outs()); +} llvm::outs() << "\n"; DelegatingDeserializationListener::DeclRead(ID, D); Index: cfe/trunk/lib/Frontend/FrontendAction.cpp === --- cfe/trunk/lib/Frontend/FrontendAction.cpp +++ cfe/trunk/lib/Frontend/FrontendAction.cpp @@ -88,8 +88,10 @@ void DeclRead(serialization::DeclID ID, const Decl *D) override { llvm::outs() << "PCH DECL: " << D->getDeclKindName(); -if (const NamedDecl *ND = dyn_cast(D)) - llvm::outs() << " - " << *ND; +if (const NamedDecl *ND = dyn_cast(D)) { + llvm::outs() << " - "; + ND->printQualifiedName(llvm::outs()); +} llvm::outs() << "\n"; DelegatingDeserializationListener::DeclRead(ID, D); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D47029: [X86] Remove some preprocessor feature checks from intrinsic headers
This revision was automatically updated to reflect the committed changes. Closed by commit rC332830: [X86] Remove some preprocessor feature checks from intrinsic headers (authored by ctopper, committed by ). Repository: rC Clang https://reviews.llvm.org/D47029 Files: lib/Headers/prfchwintrin.h lib/Headers/smmintrin.h Index: lib/Headers/smmintrin.h === --- lib/Headers/smmintrin.h +++ lib/Headers/smmintrin.h @@ -2458,8 +2458,6 @@ #undef __DEFAULT_FN_ATTRS -#ifdef __POPCNT__ #include -#endif #endif /* __SMMINTRIN_H */ Index: lib/Headers/prfchwintrin.h === --- lib/Headers/prfchwintrin.h +++ lib/Headers/prfchwintrin.h @@ -28,7 +28,6 @@ #ifndef __PRFCHWINTRIN_H #define __PRFCHWINTRIN_H -#if defined(__PRFCHW__) || defined(__3dNOW__) /// Loads a memory sequence containing the specified memory address into ///all data cache levels. The cache-coherency state is set to exclusive. ///Data can be read from and written to the cache line without additional @@ -66,6 +65,5 @@ { __builtin_prefetch (__P, 1, 3 /* _MM_HINT_T0 */); } -#endif #endif /* __PRFCHWINTRIN_H */ Index: lib/Headers/smmintrin.h === --- lib/Headers/smmintrin.h +++ lib/Headers/smmintrin.h @@ -2458,8 +2458,6 @@ #undef __DEFAULT_FN_ATTRS -#ifdef __POPCNT__ #include -#endif #endif /* __SMMINTRIN_H */ Index: lib/Headers/prfchwintrin.h === --- lib/Headers/prfchwintrin.h +++ lib/Headers/prfchwintrin.h @@ -28,7 +28,6 @@ #ifndef __PRFCHWINTRIN_H #define __PRFCHWINTRIN_H -#if defined(__PRFCHW__) || defined(__3dNOW__) /// Loads a memory sequence containing the specified memory address into ///all data cache levels. The cache-coherency state is set to exclusive. ///Data can be read from and written to the cache line without additional @@ -66,6 +65,5 @@ { __builtin_prefetch (__P, 1, 3 /* _MM_HINT_T0 */); } -#endif #endif /* __PRFCHWINTRIN_H */ ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46863: [X86] Use __builtin_convertvector to implement some of the packed integer to packed float conversion intrinsics.
This revision was automatically updated to reflect the committed changes. Closed by commit rC332882: [X86] Use __builtin_convertvector to implement some of the packed integer to… (authored by ctopper, committed by ). Changed prior to commit: https://reviews.llvm.org/D46863?vs=146750&id=147853#toc Repository: rC Clang https://reviews.llvm.org/D46863 Files: include/clang/Basic/BuiltinsX86.def lib/Headers/avx512dqintrin.h lib/Headers/avx512fintrin.h lib/Headers/avx512vldqintrin.h lib/Headers/avx512vlintrin.h lib/Headers/avxintrin.h lib/Headers/emmintrin.h test/CodeGen/avx-builtins.c test/CodeGen/avx512dq-builtins.c test/CodeGen/avx512f-builtins.c test/CodeGen/avx512vl-builtins.c test/CodeGen/avx512vldq-builtins.c test/CodeGen/builtins-x86.c test/CodeGen/sse2-builtins.c Index: include/clang/Basic/BuiltinsX86.def === --- include/clang/Basic/BuiltinsX86.def +++ include/clang/Basic/BuiltinsX86.def @@ -320,7 +320,6 @@ TARGET_BUILTIN(__builtin_ia32_psadbw128, "V2LLiV16cV16c", "nc", "sse2") TARGET_BUILTIN(__builtin_ia32_sqrtpd, "V2dV2d", "nc", "sse2") TARGET_BUILTIN(__builtin_ia32_sqrtsd, "V2dV2d", "nc", "sse2") -TARGET_BUILTIN(__builtin_ia32_cvtdq2ps, "V4fV4i", "nc", "sse2") TARGET_BUILTIN(__builtin_ia32_cvtpd2dq, "V2LLiV2d", "nc", "sse2") TARGET_BUILTIN(__builtin_ia32_cvtpd2ps, "V4fV2d", "nc", "sse2") TARGET_BUILTIN(__builtin_ia32_cvttpd2dq, "V4iV2d", "nc", "sse2") @@ -1200,8 +1199,6 @@ TARGET_BUILTIN(__builtin_ia32_cvttpd2udq256_mask, "V4iV4dV4iUc", "nc", "avx512vl") TARGET_BUILTIN(__builtin_ia32_cvttps2udq128_mask, "V4iV4fV4iUc", "nc", "avx512vl") TARGET_BUILTIN(__builtin_ia32_cvttps2udq256_mask, "V8iV8fV8iUc", "nc", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_cvtudq2ps128_mask, "V4fV4iV4fUc", "nc", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_cvtudq2ps256_mask, "V8fV8iV8fUc", "nc", "avx512vl") TARGET_BUILTIN(__builtin_ia32_expanddf128_mask, "V2dV2dV2dUc", "nc", "avx512vl") TARGET_BUILTIN(__builtin_ia32_expanddf256_mask, "V4dV4dV4dUc", "nc", "avx512vl") TARGET_BUILTIN(__builtin_ia32_expanddi128_mask, "V2LLiV2LLiV2LLiUc", "nc", "avx512vl") @@ -1363,8 +1360,6 @@ TARGET_BUILTIN(__builtin_ia32_cvtps2qq256_mask, "V4LLiV4fV4LLiUc", "nc", "avx512vl,avx512dq") TARGET_BUILTIN(__builtin_ia32_cvtps2uqq128_mask, "V2LLiV4fV2LLiUc", "nc", "avx512vl,avx512dq") TARGET_BUILTIN(__builtin_ia32_cvtps2uqq256_mask, "V4LLiV4fV4LLiUc", "nc", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtqq2pd128_mask, "V2dV2LLiV2dUc", "nc", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtqq2pd256_mask, "V4dV4LLiV4dUc", "nc", "avx512vl,avx512dq") TARGET_BUILTIN(__builtin_ia32_cvtqq2ps128_mask, "V4fV2LLiV4fUc", "nc", "avx512vl,avx512dq") TARGET_BUILTIN(__builtin_ia32_cvtqq2ps256_mask, "V4fV4LLiV4fUc", "nc", "avx512vl,avx512dq") TARGET_BUILTIN(__builtin_ia32_cvttpd2qq128_mask, "V2LLiV2dV2LLiUc", "nc", "avx512vl,avx512dq") @@ -1375,8 +1370,6 @@ TARGET_BUILTIN(__builtin_ia32_cvttps2qq256_mask, "V4LLiV4fV4LLiUc", "nc", "avx512vl,avx512dq") TARGET_BUILTIN(__builtin_ia32_cvttps2uqq128_mask, "V2LLiV4fV2LLiUc", "nc", "avx512vl,avx512dq") TARGET_BUILTIN(__builtin_ia32_cvttps2uqq256_mask, "V4LLiV4fV4LLiUc", "nc", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtuqq2pd128_mask, "V2dV2LLiV2dUc", "nc", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_cvtuqq2pd256_mask, "V4dV4LLiV4dUc", "nc", "avx512vl,avx512dq") TARGET_BUILTIN(__builtin_ia32_cvtuqq2ps128_mask, "V4fV2LLiV4fUc", "nc", "avx512vl,avx512dq") TARGET_BUILTIN(__builtin_ia32_cvtuqq2ps256_mask, "V4fV4LLiV4fUc", "nc", "avx512vl,avx512dq") TARGET_BUILTIN(__builtin_ia32_rangepd128_mask, "V2dV2dV2dIiV2dUc", "nc", "avx512vl,avx512dq") Index: test/CodeGen/avx-builtins.c === --- test/CodeGen/avx-builtins.c +++ test/CodeGen/avx-builtins.c @@ -256,7 +256,7 @@ __m256 test_mm256_cvtepi32_ps(__m256i A) { // CHECK-LABEL: test_mm256_cvtepi32_ps - // CHECK: call <8 x float> @llvm.x86.avx.cvtdq2.ps.256(<8 x i32> %{{.*}}) + // CHECK: sitofp <8 x i32> %{{.*}} to <8 x float> return _mm256_cvtepi32_ps(A); } Index: test/CodeGen/builtins-x86.c === --- test/CodeGen/builtins-x86.c +++ test/CodeGen/builtins-x86.c @@ -338,7 +338,6 @@ tmp_V2LLi = __builtin_ia32_psadbw128(tmp_V16c, tmp_V16c); tmp_V2d = __builtin_ia32_sqrtpd(tmp_V2d); tmp_V2d = __builtin_ia32_sqrtsd(tmp_V2d); - tmp_V4f = __builtin_ia32_cvtdq2ps(tmp_V4i); tmp_V2LLi = __builtin_ia32_cvtpd2dq(tmp_V2d); tmp_V2i = __builtin_ia32_cvtpd2pi(tmp_V2d); tmp_V4f = __builtin_ia32_cvtpd2ps(tmp_V2d); Index: test/CodeGen/avx512vldq-builtins.c === --- test/CodeGen/avx512vldq-builtins.c +++ test/CodeGen/avx512vldq-builtins.c @@ -421,37 +421,41 @@ __m128d test_mm_cvtepi64_pd(__m128i __A) { // CHECK-LABEL: @test_mm_cvte
[PATCH] D47125: [X86] Remove masking from pternlog llvm intrinsics and use a select instruction instead.
This revision was automatically updated to reflect the committed changes. Closed by commit rL332891: [X86] Remove masking from pternlog llvm intrinsics and use a select instruction… (authored by ctopper, committed by ). Herald added a subscriber: llvm-commits. Repository: rL LLVM https://reviews.llvm.org/D47125 Files: cfe/trunk/lib/CodeGen/CGBuiltin.cpp cfe/trunk/test/CodeGen/avx512f-builtins.c cfe/trunk/test/CodeGen/avx512vl-builtins.c Index: cfe/trunk/test/CodeGen/avx512vl-builtins.c === --- cfe/trunk/test/CodeGen/avx512vl-builtins.c +++ cfe/trunk/test/CodeGen/avx512vl-builtins.c @@ -5608,73 +5608,81 @@ __m128i test_mm_ternarylogic_epi32(__m128i __A, __m128i __B, __m128i __C) { // CHECK-LABEL: @test_mm_ternarylogic_epi32 - // CHECK: @llvm.x86.avx512.mask.pternlog.d.128 + // CHECK: @llvm.x86.avx512.pternlog.d.128 return _mm_ternarylogic_epi32(__A, __B, __C, 4); } __m128i test_mm_mask_ternarylogic_epi32(__m128i __A, __mmask8 __U, __m128i __B, __m128i __C) { // CHECK-LABEL: @test_mm_mask_ternarylogic_epi32 - // CHECK: @llvm.x86.avx512.mask.pternlog.d.128 + // CHECK: @llvm.x86.avx512.pternlog.d.128 + // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> %{{.*}} return _mm_mask_ternarylogic_epi32(__A, __U, __B, __C, 4); } __m128i test_mm_maskz_ternarylogic_epi32(__mmask8 __U, __m128i __A, __m128i __B, __m128i __C) { // CHECK-LABEL: @test_mm_maskz_ternarylogic_epi32 - // CHECK: @llvm.x86.avx512.maskz.pternlog.d.128 + // CHECK: @llvm.x86.avx512.pternlog.d.128 + // CHECK: select <4 x i1> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> zeroinitializer return _mm_maskz_ternarylogic_epi32(__U, __A, __B, __C, 4); } __m256i test_mm256_ternarylogic_epi32(__m256i __A, __m256i __B, __m256i __C) { // CHECK-LABEL: @test_mm256_ternarylogic_epi32 - // CHECK: @llvm.x86.avx512.mask.pternlog.d.256 + // CHECK: @llvm.x86.avx512.pternlog.d.256 return _mm256_ternarylogic_epi32(__A, __B, __C, 4); } __m256i test_mm256_mask_ternarylogic_epi32(__m256i __A, __mmask8 __U, __m256i __B, __m256i __C) { // CHECK-LABEL: @test_mm256_mask_ternarylogic_epi32 - // CHECK: @llvm.x86.avx512.mask.pternlog.d.256 + // CHECK: @llvm.x86.avx512.pternlog.d.256 + // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> %{{.*}} return _mm256_mask_ternarylogic_epi32(__A, __U, __B, __C, 4); } __m256i test_mm256_maskz_ternarylogic_epi32(__mmask8 __U, __m256i __A, __m256i __B, __m256i __C) { // CHECK-LABEL: @test_mm256_maskz_ternarylogic_epi32 - // CHECK: @llvm.x86.avx512.maskz.pternlog.d.256 + // CHECK: @llvm.x86.avx512.pternlog.d.256 + // CHECK: select <8 x i1> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> zeroinitializer return _mm256_maskz_ternarylogic_epi32(__U, __A, __B, __C, 4); } __m128i test_mm_ternarylogic_epi64(__m128i __A, __m128i __B, __m128i __C) { // CHECK-LABEL: @test_mm_ternarylogic_epi64 - // CHECK: @llvm.x86.avx512.mask.pternlog.q.128 + // CHECK: @llvm.x86.avx512.pternlog.q.128 return _mm_ternarylogic_epi64(__A, __B, __C, 4); } __m128i test_mm_mask_ternarylogic_epi64(__m128i __A, __mmask8 __U, __m128i __B, __m128i __C) { // CHECK-LABEL: @test_mm_mask_ternarylogic_epi64 - // CHECK: @llvm.x86.avx512.mask.pternlog.q.128 + // CHECK: @llvm.x86.avx512.pternlog.q.128 + // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}} return _mm_mask_ternarylogic_epi64(__A, __U, __B, __C, 4); } __m128i test_mm_maskz_ternarylogic_epi64(__mmask8 __U, __m128i __A, __m128i __B, __m128i __C) { // CHECK-LABEL: @test_mm_maskz_ternarylogic_epi64 - // CHECK: @llvm.x86.avx512.maskz.pternlog.q.128 + // CHECK: @llvm.x86.avx512.pternlog.q.128 + // CHECK: select <2 x i1> %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> zeroinitializer return _mm_maskz_ternarylogic_epi64(__U, __A, __B, __C, 4); } __m256i test_mm256_ternarylogic_epi64(__m256i __A, __m256i __B, __m256i __C) { // CHECK-LABEL: @test_mm256_ternarylogic_epi64 - // CHECK: @llvm.x86.avx512.mask.pternlog.q.256 + // CHECK: @llvm.x86.avx512.pternlog.q.256 return _mm256_ternarylogic_epi64(__A, __B, __C, 4); } __m256i test_mm256_mask_ternarylogic_epi64(__m256i __A, __mmask8 __U, __m256i __B, __m256i __C) { // CHECK-LABEL: @test_mm256_mask_ternarylogic_epi64 - // CHECK: @llvm.x86.avx512.mask.pternlog.q.256 + // CHECK: @llvm.x86.avx512.pternlog.q.256 + // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> %{{.*}} return _mm256_mask_ternarylogic_epi64(__A, __U, __B, __C, 4); } __m256i test_mm256_maskz_ternarylogic_epi64(__mmask8 __U, __m256i __A, __m256i __B, __m256i __C) { // CHECK-LABEL: @test_mm256_maskz_ternarylogic_epi64 - // CHECK: @llvm.x86.avx512.maskz.pternlog.q.256 + // CHECK: @llvm.x86.avx512.pternlog.q.256 + // CHECK: select <4 x i1> %{{.*}}, <4 x i64> %{{.*}}, <4 x i64> zeroinitializer return _mm256_maskz_ternarylogic_epi64(__U, __A, __B, __C, 4); } __m256 tes
[PATCH] D47066: [clangd] Remove ignored Preamble::CanReuse call from completion
This revision was automatically updated to reflect the committed changes. Closed by commit rL332976: [clangd] Remove ignored Preamble::CanReuse call from completion (authored by ibiryukov, committed by ). Herald added a subscriber: llvm-commits. Repository: rL LLVM https://reviews.llvm.org/D47066 Files: clang-tools-extra/trunk/clangd/CodeComplete.cpp Index: clang-tools-extra/trunk/clangd/CodeComplete.cpp === --- clang-tools-extra/trunk/clangd/CodeComplete.cpp +++ clang-tools-extra/trunk/clangd/CodeComplete.cpp @@ -654,21 +654,11 @@ std::unique_ptr ContentsBuffer = llvm::MemoryBuffer::getMemBufferCopy(Input.Contents, Input.FileName); + // The diagnostic options must be set before creating a CompilerInstance. + CI->getDiagnosticOpts().IgnoreWarnings = true; // We reuse the preamble whether it's valid or not. This is a // correctness/performance tradeoff: building without a preamble is slow, and // completion is latency-sensitive. - if (Input.Preamble) { -auto Bounds = -ComputePreambleBounds(*CI->getLangOpts(), ContentsBuffer.get(), 0); -// FIXME(ibiryukov): Remove this call to CanReuse() after we'll fix -// clients relying on getting stats for preamble files during code -// completion. -// Note that results of CanReuse() are ignored, see the comment above. -Input.Preamble->CanReuse(*CI, ContentsBuffer.get(), Bounds, - Input.VFS.get()); - } - // The diagnostic options must be set before creating a CompilerInstance. - CI->getDiagnosticOpts().IgnoreWarnings = true; auto Clang = prepareCompilerInstance( std::move(CI), Input.Preamble, std::move(ContentsBuffer), std::move(Input.PCHs), std::move(Input.VFS), DummyDiagsConsumer); Index: clang-tools-extra/trunk/clangd/CodeComplete.cpp === --- clang-tools-extra/trunk/clangd/CodeComplete.cpp +++ clang-tools-extra/trunk/clangd/CodeComplete.cpp @@ -654,21 +654,11 @@ std::unique_ptr ContentsBuffer = llvm::MemoryBuffer::getMemBufferCopy(Input.Contents, Input.FileName); + // The diagnostic options must be set before creating a CompilerInstance. + CI->getDiagnosticOpts().IgnoreWarnings = true; // We reuse the preamble whether it's valid or not. This is a // correctness/performance tradeoff: building without a preamble is slow, and // completion is latency-sensitive. - if (Input.Preamble) { -auto Bounds = -ComputePreambleBounds(*CI->getLangOpts(), ContentsBuffer.get(), 0); -// FIXME(ibiryukov): Remove this call to CanReuse() after we'll fix -// clients relying on getting stats for preamble files during code -// completion. -// Note that results of CanReuse() are ignored, see the comment above. -Input.Preamble->CanReuse(*CI, ContentsBuffer.get(), Bounds, - Input.VFS.get()); - } - // The diagnostic options must be set before creating a CompilerInstance. - CI->getDiagnosticOpts().IgnoreWarnings = true; auto Clang = prepareCompilerInstance( std::move(CI), Input.Preamble, std::move(ContentsBuffer), std::move(Input.PCHs), std::move(Input.VFS), DummyDiagsConsumer); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D47174: [X86] Move 128-bit f16c intrinsics to __emmintrin_f16c.h include from emmintrin.h. Move 256-bit f16c intrinsics back to f16cintrin.h
This revision was automatically updated to reflect the committed changes. Closed by commit rL333014: [X86] Move 128-bit f16c intrinsics to __emmintrin_f16c.h include from emmintrin. (authored by ctopper, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D47174?vs=147932&id=148065#toc Repository: rL LLVM https://reviews.llvm.org/D47174 Files: cfe/trunk/lib/Headers/__emmintrin_f16c.h cfe/trunk/lib/Headers/emmintrin.h cfe/trunk/lib/Headers/f16cintrin.h cfe/trunk/lib/Headers/immintrin.h Index: cfe/trunk/lib/Headers/immintrin.h === --- cfe/trunk/lib/Headers/immintrin.h +++ cfe/trunk/lib/Headers/immintrin.h @@ -69,54 +69,8 @@ #if !defined(_MSC_VER) || __has_feature(modules) || defined(__AVX2__) #include -/* The 256-bit versions of functions in f16cintrin.h. - Intel documents these as being in immintrin.h, and - they depend on typedefs from avxintrin.h. */ - -/// Converts a 256-bit vector of [8 x float] into a 128-bit vector -///containing 16-bit half-precision float values. -/// -/// \headerfile -/// -/// \code -/// __m128i _mm256_cvtps_ph(__m256 a, const int imm); -/// \endcode -/// -/// This intrinsic corresponds to the VCVTPS2PH instruction. -/// -/// \param a -///A 256-bit vector containing 32-bit single-precision float values to be -///converted to 16-bit half-precision float values. -/// \param imm -///An immediate value controlling rounding using bits [2:0]: \n -///000: Nearest \n -///001: Down \n -///010: Up \n -///011: Truncate \n -///1XX: Use MXCSR.RC for rounding -/// \returns A 128-bit vector containing the converted 16-bit half-precision -///float values. -#define _mm256_cvtps_ph(a, imm) __extension__ ({ \ - (__m128i)__builtin_ia32_vcvtps2ph256((__v8sf)(__m256)(a), (imm)); }) - -/// Converts a 128-bit vector containing 16-bit half-precision float -///values into a 256-bit vector of [8 x float]. -/// -/// \headerfile -/// -/// This intrinsic corresponds to the VCVTPH2PS instruction. -/// -/// \param __a -///A 128-bit vector containing 16-bit half-precision float values to be -///converted to 32-bit single-precision float values. -/// \returns A vector of [8 x float] containing the converted 32-bit -///single-precision float values. -static __inline __m256 __attribute__((__always_inline__, __nodebug__, __target__("f16c"))) -_mm256_cvtph_ps(__m128i __a) -{ - return (__m256)__builtin_ia32_vcvtph2ps256((__v8hi)__a); -} -#endif /* __AVX2__ */ +#if !defined(_MSC_VER) || __has_feature(modules) || defined(__F16C__) +#include #if !defined(_MSC_VER) || __has_feature(modules) || defined(__VPCLMULQDQ__) #include Index: cfe/trunk/lib/Headers/emmintrin.h === --- cfe/trunk/lib/Headers/emmintrin.h +++ cfe/trunk/lib/Headers/emmintrin.h @@ -44,7 +44,7 @@ * appear in the interface though. */ typedef signed char __v16qs __attribute__((__vector_size__(16))); -#include +#include <__emmintrin_f16c.h> /* Define the default attributes for the functions in this file. */ #define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("sse2"))) Index: cfe/trunk/lib/Headers/f16cintrin.h === --- cfe/trunk/lib/Headers/f16cintrin.h +++ cfe/trunk/lib/Headers/f16cintrin.h @@ -21,8 +21,8 @@ *===---=== */ -#if !defined __X86INTRIN_H && !defined __EMMINTRIN_H && !defined __IMMINTRIN_H -#error "Never use directly; include instead." +#if !defined __IMMINTRIN_H +#error "Never use directly; include instead." #endif #ifndef __F16CINTRIN_H @@ -32,91 +32,52 @@ #define __DEFAULT_FN_ATTRS \ __attribute__((__always_inline__, __nodebug__, __target__("f16c"))) -/// Converts a 16-bit half-precision float value into a 32-bit float -///value. -/// -/// \headerfile -/// -/// This intrinsic corresponds to the VCVTPH2PS instruction. -/// -/// \param __a -///A 16-bit half-precision float value. -/// \returns The converted 32-bit float value. -static __inline float __DEFAULT_FN_ATTRS -_cvtsh_ss(unsigned short __a) -{ - __v8hi v = {(short)__a, 0, 0, 0, 0, 0, 0, 0}; - __v4sf r = __builtin_ia32_vcvtph2ps(v); - return r[0]; -} - -/// Converts a 32-bit single-precision float value to a 16-bit -///half-precision float value. -/// -/// \headerfile -/// -/// \code -/// unsigned short _cvtss_sh(float a, const int imm); -/// \endcode -/// -/// This intrinsic corresponds to the VCVTPS2PH instruction. -/// -/// \param a -///A 32-bit single-precision float value to be converted to a 16-bit -///half-precision float value. -/// \param imm -///An immediate value controlling rounding using bits [2:0]: \n -///000: Nearest \n -///001: Down \n -///010: Up \n -///011: Trunc
[PATCH] D47182: [X86] Move all Intel defined intrinsic includes into immintrin.h
This revision was automatically updated to reflect the committed changes. Closed by commit rL333110: [X86] Move all Intel defined intrinsic includes into immintrin.h (authored by ctopper, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D47182?vs=148252&id=148259#toc Repository: rL LLVM https://reviews.llvm.org/D47182 Files: cfe/trunk/lib/Headers/cldemoteintrin.h cfe/trunk/lib/Headers/clzerointrin.h cfe/trunk/lib/Headers/immintrin.h cfe/trunk/lib/Headers/movdirintrin.h cfe/trunk/lib/Headers/pconfigintrin.h cfe/trunk/lib/Headers/ptwriteintrin.h cfe/trunk/lib/Headers/rdseedintrin.h cfe/trunk/lib/Headers/sgxintrin.h cfe/trunk/lib/Headers/waitpkgintrin.h cfe/trunk/lib/Headers/wbnoinvdintrin.h cfe/trunk/lib/Headers/x86intrin.h Index: cfe/trunk/lib/Headers/wbnoinvdintrin.h === --- cfe/trunk/lib/Headers/wbnoinvdintrin.h +++ cfe/trunk/lib/Headers/wbnoinvdintrin.h @@ -21,7 +21,7 @@ *===---=== */ -#ifndef __X86INTRIN_H +#if !defined __X86INTRIN_H && !defined __IMMINTRIN_H #error "Never use directly; include instead." #endif Index: cfe/trunk/lib/Headers/waitpkgintrin.h === --- cfe/trunk/lib/Headers/waitpkgintrin.h +++ cfe/trunk/lib/Headers/waitpkgintrin.h @@ -20,7 +20,7 @@ * *===---=== */ -#ifndef __X86INTRIN_H +#if !defined __X86INTRIN_H && !defined __IMMINTRIN_H #error "Never use directly; include instead." #endif Index: cfe/trunk/lib/Headers/movdirintrin.h === --- cfe/trunk/lib/Headers/movdirintrin.h +++ cfe/trunk/lib/Headers/movdirintrin.h @@ -20,7 +20,7 @@ * *===---=== */ -#ifndef __X86INTRIN_H +#if !defined __X86INTRIN_H && !defined __IMMINTRIN_H #error "Never use directly; include instead." #endif Index: cfe/trunk/lib/Headers/pconfigintrin.h === --- cfe/trunk/lib/Headers/pconfigintrin.h +++ cfe/trunk/lib/Headers/pconfigintrin.h @@ -21,7 +21,7 @@ *===---=== */ -#ifndef __X86INTRIN_H +#if !defined __X86INTRIN_H && !defined __IMMINTRIN_H #error "Never use directly; include instead." #endif Index: cfe/trunk/lib/Headers/immintrin.h === --- cfe/trunk/lib/Headers/immintrin.h +++ cfe/trunk/lib/Headers/immintrin.h @@ -90,6 +90,10 @@ #include #endif +#if !defined(_MSC_VER) || __has_feature(modules) || defined(__POPCNT__) +#include +#endif + #if !defined(_MSC_VER) || __has_feature(modules) || defined(__FMA__) #include #endif @@ -339,4 +343,41 @@ * whereas others are also available at all times. */ #include +#if !defined(_MSC_VER) || __has_feature(modules) || defined(__RDSEED__) +#include +#endif + +#if !defined(_MSC_VER) || __has_feature(modules) || defined(__CLZERO__) +#include +#endif + +#if !defined(_MSC_VER) || __has_feature(modules) || defined(__WBNOINVD__) +#include +#endif + +#if !defined(_MSC_VER) || __has_feature(modules) || defined(__CLDEMOTE__) +#include +#endif + +#if !defined(_MSC_VER) || __has_feature(modules) || defined(__WAITPKG__) +#include +#endif + +#if !defined(_MSC_VER) || __has_feature(modules) || \ + defined(__MOVDIRI__) || defined(__MOVDIR64B__) +#include +#endif + +#if !defined(_MSC_VER) || __has_feature(modules) || defined(__PCONFIG__) +#include +#endif + +#if !defined(_MSC_VER) || __has_feature(modules) || defined(__SGX__) +#include +#endif + +#if !defined(_MSC_VER) || __has_feature(modules) || defined(__PTWRITE__) +#include +#endif + #endif /* __IMMINTRIN_H */ Index: cfe/trunk/lib/Headers/ptwriteintrin.h === --- cfe/trunk/lib/Headers/ptwriteintrin.h +++ cfe/trunk/lib/Headers/ptwriteintrin.h @@ -21,7 +21,7 @@ *===---=== */ -#ifndef __X86INTRIN_H +#if !defined __X86INTRIN_H && !defined __IMMINTRIN_H #error "Never use directly; include instead." #endif Index: cfe/trunk/lib/Headers/sgxintrin.h === --- cfe/trunk/lib/Headers/sgxintrin.h +++ cfe/trunk/lib/Headers/sgxintrin.h @@ -21,7 +21,7 @@ *===---=== */ -#ifndef __X86INTRIN_H +#if !defined __X86INTRIN_H && !defined __IMMINTRIN_H #error "Never use directly; include instead." #endif Index: cfe/trunk/lib/Headers/cldemoteintrin.h === --- cfe/trunk/lib/Headers/clde
[PATCH] D45920: [analyzer] Move RangeSet related declarations into the RangedConstraintManager header.
This revision was automatically updated to reflect the committed changes. Closed by commit rC333179: [analyzer] Move RangeSet related declarations into the RangedConstraintManager… (authored by mramalho, committed by ). Repository: rC Clang https://reviews.llvm.org/D45920 Files: lib/StaticAnalyzer/Core/RangeConstraintManager.cpp lib/StaticAnalyzer/Core/RangedConstraintManager.h Index: lib/StaticAnalyzer/Core/RangeConstraintManager.cpp === --- lib/StaticAnalyzer/Core/RangeConstraintManager.cpp +++ lib/StaticAnalyzer/Core/RangeConstraintManager.cpp @@ -23,263 +23,171 @@ using namespace clang; using namespace ento; -/// A Range represents the closed range [from, to]. The caller must -/// guarantee that from <= to. Note that Range is immutable, so as not -/// to subvert RangeSet's immutability. -namespace { -class Range : public std::pair { -public: - Range(const llvm::APSInt &from, const llvm::APSInt &to) - : std::pair(&from, &to) { -assert(from <= to); - } - bool Includes(const llvm::APSInt &v) const { -return *first <= v && v <= *second; - } - const llvm::APSInt &From() const { return *first; } - const llvm::APSInt &To() const { return *second; } - const llvm::APSInt *getConcreteValue() const { -return &From() == &To() ? &From() : nullptr; - } - - void Profile(llvm::FoldingSetNodeID &ID) const { -ID.AddPointer(&From()); -ID.AddPointer(&To()); - } -}; - -class RangeTrait : public llvm::ImutContainerInfo { -public: - // When comparing if one Range is less than another, we should compare - // the actual APSInt values instead of their pointers. This keeps the order - // consistent (instead of comparing by pointer values) and can potentially - // be used to speed up some of the operations in RangeSet. - static inline bool isLess(key_type_ref lhs, key_type_ref rhs) { -return *lhs.first < *rhs.first || - (!(*rhs.first < *lhs.first) && *lhs.second < *rhs.second); - } -}; - -/// RangeSet contains a set of ranges. If the set is empty, then -/// there the value of a symbol is overly constrained and there are no -/// possible values for that symbol. -class RangeSet { - typedef llvm::ImmutableSet PrimRangeSet; - PrimRangeSet ranges; // no need to make const, since it is an - // ImmutableSet - this allows default operator= - // to work. -public: - typedef PrimRangeSet::Factory Factory; - typedef PrimRangeSet::iterator iterator; - - RangeSet(PrimRangeSet RS) : ranges(RS) {} - - /// Create a new set with all ranges of this set and RS. - /// Possible intersections are not checked here. - RangeSet addRange(Factory &F, const RangeSet &RS) { -PrimRangeSet Ranges(RS.ranges); -for (const auto &range : ranges) - Ranges = F.add(Ranges, range); -return RangeSet(Ranges); - } - - iterator begin() const { return ranges.begin(); } - iterator end() const { return ranges.end(); } - - bool isEmpty() const { return ranges.isEmpty(); } - - /// Construct a new RangeSet representing '{ [from, to] }'. - RangeSet(Factory &F, const llvm::APSInt &from, const llvm::APSInt &to) - : ranges(F.add(F.getEmptySet(), Range(from, to))) {} - - /// Profile - Generates a hash profile of this RangeSet for use - /// by FoldingSet. - void Profile(llvm::FoldingSetNodeID &ID) const { ranges.Profile(ID); } - - /// getConcreteValue - If a symbol is contrained to equal a specific integer - /// constant then this method returns that value. Otherwise, it returns - /// NULL. - const llvm::APSInt *getConcreteValue() const { -return ranges.isSingleton() ? ranges.begin()->getConcreteValue() : nullptr; - } +void RangeSet::IntersectInRange(BasicValueFactory &BV, Factory &F, + const llvm::APSInt &Lower, const llvm::APSInt &Upper, + PrimRangeSet &newRanges, PrimRangeSet::iterator &i, + PrimRangeSet::iterator &e) const { + // There are six cases for each range R in the set: + // 1. R is entirely before the intersection range. + // 2. R is entirely after the intersection range. + // 3. R contains the entire intersection range. + // 4. R starts before the intersection range and ends in the middle. + // 5. R starts in the middle of the intersection range and ends after it. + // 6. R is entirely contained in the intersection range. + // These correspond to each of the conditions below. + for (/* i = begin(), e = end() */; i != e; ++i) { +if (i->To() < Lower) { + continue; +} +if (i->From() > Upper) { + break; +} -private: - void IntersectInRange(BasicValueFactory &BV, Factory &F, -const llvm::APSInt &Lower, const llvm::APSInt &Upper, -PrimRangeSet &newRanges, PrimRangeSet::iterator &i, -PrimRangeSet::iterator &e) const { -// There are six cases for each range R in
[PATCH] D47274: [clangd] Serve comments for headers decls from dynamic index only
This revision was automatically updated to reflect the committed changes. Closed by commit rL333189: [clangd] Serve comments for headers decls from dynamic index only (authored by ibiryukov, committed by ). Herald added a subscriber: llvm-commits. Repository: rL LLVM https://reviews.llvm.org/D47274 Files: clang-tools-extra/trunk/clangd/CodeComplete.cpp clang-tools-extra/trunk/clangd/CodeCompletionStrings.cpp clang-tools-extra/trunk/clangd/CodeCompletionStrings.h clang-tools-extra/trunk/clangd/index/SymbolCollector.cpp clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp Index: clang-tools-extra/trunk/clangd/CodeComplete.cpp === --- clang-tools-extra/trunk/clangd/CodeComplete.cpp +++ clang-tools-extra/trunk/clangd/CodeComplete.cpp @@ -586,9 +586,11 @@ const auto *CCS = Candidate.CreateSignatureString( CurrentArg, S, *Allocator, CCTUInfo, true); assert(CCS && "Expected the CodeCompletionString to be non-null"); + // FIXME: for headers, we need to get a comment from the index. SigHelp.signatures.push_back(ProcessOverloadCandidate( Candidate, *CCS, - getParameterDocComment(S.getASTContext(), Candidate, CurrentArg))); + getParameterDocComment(S.getASTContext(), Candidate, CurrentArg, + /*CommentsFromHeader=*/false))); } } @@ -1030,7 +1032,8 @@ SemaCCS = Recorder->codeCompletionString(*SR); if (Opts.IncludeComments) { assert(Recorder->CCSema); -DocComment = getDocComment(Recorder->CCSema->getASTContext(), *SR); +DocComment = getDocComment(Recorder->CCSema->getASTContext(), *SR, + /*CommentsFromHeader=*/false); } } return Candidate.build(FileName, Scores, Opts, SemaCCS, Includes.get(), DocComment); Index: clang-tools-extra/trunk/clangd/CodeCompletionStrings.cpp === --- clang-tools-extra/trunk/clangd/CodeCompletionStrings.cpp +++ clang-tools-extra/trunk/clangd/CodeCompletionStrings.cpp @@ -10,6 +10,7 @@ #include "CodeCompletionStrings.h" #include "clang/AST/ASTContext.h" #include "clang/AST/RawCommentList.h" +#include "clang/Basic/SourceManager.h" #include namespace clang { @@ -122,10 +123,23 @@ } } +std::string getFormattedComment(const ASTContext &Ctx, const RawComment &RC, +bool CommentsFromHeaders) { + auto &SourceMgr = Ctx.getSourceManager(); + // Parsing comments from invalid preamble can lead to crashes. So we only + // return comments from the main file when doing code completion. For + // indexing, we still read all the comments. + // FIXME: find a better fix, e.g. store file contents in the preamble or get + // doc comments from the index. + if (!CommentsFromHeaders && !SourceMgr.isWrittenInMainFile(RC.getLocStart())) +return ""; + return RC.getFormattedText(Ctx.getSourceManager(), Ctx.getDiagnostics()); +} } // namespace std::string getDocComment(const ASTContext &Ctx, - const CodeCompletionResult &Result) { + const CodeCompletionResult &Result, + bool CommentsFromHeaders) { // FIXME: clang's completion also returns documentation for RK_Pattern if they // contain a pattern for ObjC properties. Unfortunately, there is no API to // get this declaration, so we don't show documentation in that case. @@ -137,20 +151,20 @@ const RawComment *RC = getCompletionComment(Ctx, Decl); if (!RC) return ""; - return RC->getFormattedText(Ctx.getSourceManager(), Ctx.getDiagnostics()); + return getFormattedComment(Ctx, *RC, CommentsFromHeaders); } std::string getParameterDocComment(const ASTContext &Ctx, const CodeCompleteConsumer::OverloadCandidate &Result, - unsigned ArgIndex) { + unsigned ArgIndex, bool CommentsFromHeaders) { auto Func = Result.getFunction(); if (!Func) return ""; const RawComment *RC = getParameterComment(Ctx, Result, ArgIndex); if (!RC) return ""; - return RC->getFormattedText(Ctx.getSourceManager(), Ctx.getDiagnostics()); + return getFormattedComment(Ctx, *RC, CommentsFromHeaders); } void getLabelAndInsertText(const CodeCompletionString &CCS, std::string *Label, Index: clang-tools-extra/trunk/clangd/index/SymbolCollector.cpp === --- clang-tools-extra/trunk/clangd/index/SymbolCollector.cpp +++ clang-tools-extra/trunk/clangd/index/SymbolCollector.cpp @@ -389,7 +389,8 @@ /*EnableSnippets=*/false); std::string FilterText = getFilterText(*CCS); std::string Documentation = - formatDocumentation(*CCS, getDocComment(Ctx, SymbolCompletion)); + formatDocumentation(*CCS, getDocComment(Ctx, SymbolCompletion
[PATCH] D47272: [clangd] Build index on preamble changes instead of the AST changes
This revision was automatically updated to reflect the committed changes. Closed by commit rCTE333196: [clangd] Build index on preamble changes instead of the AST changes (authored by ibiryukov, committed by ). Changed prior to commit: https://reviews.llvm.org/D47272?vs=148421&id=148424#toc Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D47272 Files: clangd/ClangdServer.cpp clangd/ClangdUnit.cpp clangd/ClangdUnit.h clangd/TUScheduler.cpp clangd/TUScheduler.h clangd/index/FileIndex.cpp clangd/index/FileIndex.h unittests/clangd/FileIndexTests.cpp unittests/clangd/TUSchedulerTests.cpp unittests/clangd/TestTU.cpp Index: unittests/clangd/FileIndexTests.cpp === --- unittests/clangd/FileIndexTests.cpp +++ unittests/clangd/FileIndexTests.cpp @@ -7,8 +7,13 @@ // //===--===// +#include "ClangdUnit.h" +#include "TestFS.h" #include "TestTU.h" #include "index/FileIndex.h" +#include "clang/Frontend/PCHContainerOperations.h" +#include "clang/Lex/Preprocessor.h" +#include "clang/Tooling/CompilationDatabase.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -87,7 +92,7 @@ File.HeaderFilename = (Basename + ".h").str(); File.HeaderCode = Code; auto AST = File.build(); - M.update(File.Filename, &AST); + M.update(File.Filename, &AST.getASTContext(), AST.getPreprocessorPtr()); } TEST(FileIndexTest, IndexAST) { @@ -129,13 +134,13 @@ Req.Scopes = {"ns::"}; EXPECT_THAT(match(M, Req), UnorderedElementsAre("ns::f", "ns::X")); - M.update("f1.cpp", nullptr); + M.update("f1.cpp", nullptr, nullptr); EXPECT_THAT(match(M, Req), UnorderedElementsAre()); } TEST(FileIndexTest, RemoveNonExisting) { FileIndex M; - M.update("no.cpp", nullptr); + M.update("no.cpp", nullptr, nullptr); EXPECT_THAT(match(M, FuzzyFindRequest()), UnorderedElementsAre()); } @@ -200,6 +205,58 @@ EXPECT_TRUE(SeenMakeVector); } +TEST(FileIndexTest, RebuildWithPreamble) { + auto FooCpp = testPath("foo.cpp"); + auto FooH = testPath("foo.h"); + FileIndex Index; + bool IndexUpdated = false; + CppFile File("foo.cpp", /*StorePreambleInMemory=*/true, + std::make_shared(), + [&Index, &IndexUpdated](PathRef FilePath, ASTContext &Ctx, + std::shared_ptr PP) { + EXPECT_FALSE(IndexUpdated) + << "Expected only a single index update"; + IndexUpdated = true; + Index.update(FilePath, &Ctx, std::move(PP)); + }); + + // Preparse ParseInputs. + ParseInputs PI; + PI.CompileCommand.Directory = testRoot(); + PI.CompileCommand.Filename = FooCpp; + PI.CompileCommand.CommandLine = {"clang", "-xc++", FooCpp}; + + llvm::StringMap Files; + Files[FooCpp] = ""; + Files[FooH] = R"cpp( +namespace ns_in_header { + int func_in_header(); +} + )cpp"; + PI.FS = buildTestFS(std::move(Files)); + + PI.Contents = R"cpp( +#include "foo.h" +namespace ns_in_source { + int func_in_source(); +} + )cpp"; + + // Rebuild the file. + File.rebuild(std::move(PI)); + ASSERT_TRUE(IndexUpdated); + + // Check the index contains symbols from the preamble, but not from the main + // file. + FuzzyFindRequest Req; + Req.Query = ""; + Req.Scopes = {"", "ns_in_header::"}; + + EXPECT_THAT( + match(Index, Req), + UnorderedElementsAre("ns_in_header", "ns_in_header::func_in_header")); +} + } // namespace } // namespace clangd } // namespace clang Index: unittests/clangd/TestTU.cpp === --- unittests/clangd/TestTU.cpp +++ unittests/clangd/TestTU.cpp @@ -43,7 +43,7 @@ SymbolSlab TestTU::headerSymbols() const { auto AST = build(); - return indexAST(&AST); + return indexAST(AST.getASTContext(), AST.getPreprocessorPtr()); } std::unique_ptr TestTU::index() const { Index: unittests/clangd/TUSchedulerTests.cpp === --- unittests/clangd/TUSchedulerTests.cpp +++ unittests/clangd/TUSchedulerTests.cpp @@ -42,7 +42,7 @@ TEST_F(TUSchedulerTests, MissingFiles) { TUScheduler S(getDefaultAsyncThreadsCount(), /*StorePreamblesInMemory=*/true, -/*ASTParsedCallback=*/nullptr, +/*PreambleParsedCallback=*/nullptr, /*UpdateDebounce=*/std::chrono::steady_clock::duration::zero()); auto Added = testPath("added.cpp"); @@ -98,7 +98,7 @@ TUScheduler S( getDefaultAsyncThreadsCount(), /*StorePreamblesInMemory=*/true, -/*ASTParsedCallback=*/nullptr, +/*PreambleParsedCallback=*/nullptr, /*UpdateDebounce=*/std::chrono::steady_clock::duration::zero()); auto Path = testPath("foo.cpp"); S.update(Path, getInputs(Path, ""), WantDiagnostics::Yes, @@ -126,7 +126,7
[PATCH] D41881: [analyzer] Flag bcmp, bcopy and bzero as obsolete
This revision was automatically updated to reflect the committed changes. Closed by commit rC26: [analyzer] Add security checks for bcmp(), bcopy(), bzero(). (authored by dergachev, committed by ). Repository: rC Clang https://reviews.llvm.org/D41881 Files: include/clang/StaticAnalyzer/Checkers/Checkers.td lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp test/Analysis/security-syntax-checks.m www/analyzer/available_checks.html Index: www/analyzer/available_checks.html === --- www/analyzer/available_checks.html +++ www/analyzer/available_checks.html @@ -1173,6 +1173,40 @@ +security.insecureAPI.bcmp +(C) +Warn on uses of the bcmp function. + + +void test() { + bcmp(ptr0, ptr1, n); // warn +} + + + +security.insecureAPI.bcopy +(C) +Warn on uses of the bcopy function. + + +void test() { + bcopy(src, dst, n); // warn +} + + + +security.insecureAPI.bzero +(C) +Warn on uses of the bzero function. + + +void test() { + bzero(ptr, n); // warn +} + + + + security.insecureAPI.getpw (C) Warn on uses of the getpw function. Index: include/clang/StaticAnalyzer/Checkers/Checkers.td === --- include/clang/StaticAnalyzer/Checkers/Checkers.td +++ include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -373,6 +373,15 @@ //===--===// let ParentPackage = InsecureAPI in { + def bcmp : Checker<"bcmp">, +HelpText<"Warn on uses of the 'bcmp' function">, +DescFile<"CheckSecuritySyntaxOnly.cpp">; + def bcopy : Checker<"bcopy">, +HelpText<"Warn on uses of the 'bcopy' function">, +DescFile<"CheckSecuritySyntaxOnly.cpp">; + def bzero : Checker<"bzero">, +HelpText<"Warn on uses of the 'bzero' function">, +DescFile<"CheckSecuritySyntaxOnly.cpp">; def gets : Checker<"gets">, HelpText<"Warn on uses of the 'gets' function">, DescFile<"CheckSecuritySyntaxOnly.cpp">; Index: test/Analysis/security-syntax-checks.m === --- test/Analysis/security-syntax-checks.m +++ test/Analysis/security-syntax-checks.m @@ -37,6 +37,27 @@ for (FooType x = 10001.0f; x <= 10010.0f; x++ ) {} // expected-warning{{Variable 'x' with floating point type 'FooType'}} } +// Obsolete function bcmp +int bcmp(void *, void *, size_t); + +int test_bcmp(void *a, void *b, size_t n) { + return bcmp(a, b, n); // expected-warning{{The bcmp() function is obsoleted by memcmp()}} +} + +// Obsolete function bcopy +void bcopy(void *, void *, size_t); + +void test_bcopy(void *a, void *b, size_t n) { + bcopy(a, b, n); // expected-warning{{The bcopy() function is obsoleted by memcpy() or memmove(}} +} + +// Obsolete function bzero +void bzero(void *, size_t); + +void test_bzero(void *a, size_t n) { + bzero(a, n); // expected-warning{{The bzero() function is obsoleted by memset()}} +} + // rule request: gets() buffer overflow // Part of recommendation: 300-BSI (buildsecurityin.us-cert.gov) char* gets(char *buf); Index: lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp === --- lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp +++ lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp @@ -37,6 +37,9 @@ namespace { struct ChecksFilter { + DefaultBool check_bcmp; + DefaultBool check_bcopy; + DefaultBool check_bzero; DefaultBool check_gets; DefaultBool check_getpw; DefaultBool check_mktemp; @@ -47,6 +50,9 @@ DefaultBool check_FloatLoopCounter; DefaultBool check_UncheckedReturn; + CheckName checkName_bcmp; + CheckName checkName_bcopy; + CheckName checkName_bzero; CheckName checkName_gets; CheckName checkName_getpw; CheckName checkName_mktemp; @@ -89,6 +95,9 @@ // Checker-specific methods. void checkLoopConditionForFloat(const ForStmt *FS); + void checkCall_bcmp(const CallExpr *CE, const FunctionDecl *FD); + void checkCall_bcopy(const CallExpr *CE, const FunctionDecl *FD); + void checkCall_bzero(const CallExpr *CE, const FunctionDecl *FD); void checkCall_gets(const CallExpr *CE, const FunctionDecl *FD); void checkCall_getpw(const CallExpr *CE, const FunctionDecl *FD); void checkCall_mktemp(const CallExpr *CE, const FunctionDecl *FD); @@ -129,6 +138,9 @@ // Set the evaluation function by switching on the callee name. FnCheck evalFunction = llvm::StringSwitch(Name) +.Case("bcmp", &WalkAST::checkCall_bcmp) +.Case("bcopy", &WalkAST::checkCall_bcopy) +.Case("bzero", &WalkAST::checkCall_bzero) .Case("gets", &WalkAST::checkCall_gets) .Case("getpw", &WalkAST::checkCall_getpw) .Case("mktemp", &WalkAST::checkCall_mktemp) @@ -296,6 +308,132 @@ } //===--===// +// Check: Any use of bcmp. +// CWE-477: Use of Obsolete Function
[PATCH] D47331: [clangd] Remove accessors for top-level decls from preamble
This revision was automatically updated to reflect the committed changes. Closed by commit rCTE71: [clangd] Remove accessors for top-level decls from preamble (authored by ibiryukov, committed by ). Changed prior to commit: https://reviews.llvm.org/D47331?vs=148605&id=148806#toc Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D47331 Files: clangd/ClangdUnit.cpp clangd/ClangdUnit.h clangd/XRefs.cpp unittests/clangd/TestTU.cpp Index: unittests/clangd/TestTU.cpp === --- unittests/clangd/TestTU.cpp +++ unittests/clangd/TestTU.cpp @@ -1,5 +1,4 @@ -//===--- TestTU.cpp - Scratch source files for testing *- -//C++-*-===// +//===--- TestTU.cpp - Scratch source files for testing ===// // // The LLVM Compiler Infrastructure // @@ -73,22 +72,24 @@ } const NamedDecl &findDecl(ParsedAST &AST, llvm::StringRef QName) { - const NamedDecl *Result = nullptr; - for (const Decl *D : AST.getTopLevelDecls()) { -auto *ND = dyn_cast(D); -if (!ND || ND->getNameAsString() != QName) - continue; -if (Result) { - ADD_FAILURE() << "Multiple Decls named " << QName; - assert(false && "QName is not unique"); -} -Result = ND; - } - if (!Result) { -ADD_FAILURE() << "No Decl named " << QName << " in AST"; -assert(false && "No Decl with QName"); + llvm::SmallVector Components; + QName.split(Components, "::"); + + auto &Ctx = AST.getASTContext(); + auto LookupDecl = [&Ctx](const DeclContext &Scope, + llvm::StringRef Name) -> const NamedDecl & { +auto LookupRes = Scope.lookup(DeclarationName(&Ctx.Idents.get(Name))); +assert(!LookupRes.empty() && "Lookup failed"); +assert(LookupRes.size() == 1 && "Lookup returned multiple results"); +return *LookupRes.front(); + }; + + const DeclContext *Scope = Ctx.getTranslationUnitDecl(); + for (auto NameIt = Components.begin(), End = Components.end() - 1; + NameIt != End; ++NameIt) { +Scope = &cast(LookupDecl(*Scope, *NameIt)); } - return *Result; + return LookupDecl(*Scope, Components.back()); } } // namespace clangd Index: clangd/ClangdUnit.h === --- clangd/ClangdUnit.h +++ clangd/ClangdUnit.h @@ -44,12 +44,10 @@ // Stores Preamble and associated data. struct PreambleData { - PreambleData(PrecompiledPreamble Preamble, - std::vector TopLevelDeclIDs, - std::vector Diags, std::vector Inclusions); + PreambleData(PrecompiledPreamble Preamble, std::vector Diags, + std::vector Inclusions); PrecompiledPreamble Preamble; - std::vector TopLevelDeclIDs; std::vector Diags; // Processes like code completions and go-to-definitions will need #include // information, and their compile action skips preamble range. @@ -80,17 +78,19 @@ ~ParsedAST(); + /// Note that the returned ast will not contain decls from the preamble that + /// were not deserialized during parsing. Clients should expect only decls + /// from the main file to be in the AST. ASTContext &getASTContext(); const ASTContext &getASTContext() const; Preprocessor &getPreprocessor(); std::shared_ptr getPreprocessorPtr(); const Preprocessor &getPreprocessor() const; - /// This function returns all top-level decls, including those that come - /// from Preamble. Decls, coming from Preamble, have to be deserialized, so - /// this call might be expensive. - ArrayRef getTopLevelDecls(); + /// This function returns top-level decls present in the main file of the AST. + /// The result does not include the decls that come from the preamble. + ArrayRef getLocalTopLevelDecls(); const std::vector &getDiagnostics() const; @@ -103,11 +103,8 @@ ParsedAST(std::shared_ptr Preamble, std::unique_ptr Clang, std::unique_ptr Action, -std::vector TopLevelDecls, std::vector Diags, -std::vector Inclusions); - -private: - void ensurePreambleDeclsDeserialized(); +std::vector LocalTopLevelDecls, +std::vector Diags, std::vector Inclusions); // In-memory preambles must outlive the AST, it is important that this member // goes before Clang and Action. @@ -122,8 +119,9 @@ // Data, stored after parsing. std::vector Diags; - std::vector TopLevelDecls; - bool PreambleDeclsDeserialized; + // Top-level decls inside the current file. Not that this does not include + // top-level decls from the preamble. + std::vector LocalTopLevelDecls; std::vector Inclusions; }; Index: clangd/ClangdUnit.cpp === --- clangd/ClangdUnit.cpp +++ clangd/ClangdUnit.cpp @@ -90,37 +90,15 @@ CppFilePreambleCallbacks(PathRef File, PreambleParsedCallback ParsedCallback) : File(File), ParsedCallback(ParsedCallback) {}
[PATCH] D44888: [RISCV] Add -mrelax/-mno-relax flags to enable/disable RISCV linker relaxation
This revision was automatically updated to reflect the committed changes. Closed by commit rL85: [RISCV] Add -mrelax/-mno-relax flags to enable/disable RISCV linker relaxation (authored by shiva, committed by ). Changed prior to commit: https://reviews.llvm.org/D44888?vs=148548&id=148840#toc Repository: rL LLVM https://reviews.llvm.org/D44888 Files: cfe/trunk/include/clang/Driver/Options.td cfe/trunk/lib/Driver/ToolChains/Arch/RISCV.cpp cfe/trunk/test/Driver/riscv-features.c Index: cfe/trunk/include/clang/Driver/Options.td === --- cfe/trunk/include/clang/Driver/Options.td +++ cfe/trunk/include/clang/Driver/Options.td @@ -151,6 +151,8 @@ Group, DocName<"WebAssembly">; def m_x86_Features_Group : OptionGroup<"">, Group, Flags<[CoreOption]>, DocName<"X86">; +def m_riscv_Features_Group : OptionGroup<"">, + Group, DocName<"RISCV">; def m_libc_Group : OptionGroup<"">, Group, Flags<[HelpHidden]>; @@ -1947,6 +1949,11 @@ def mno_soft_float : Flag<["-"], "mno-soft-float">, Group; def mno_stackrealign : Flag<["-"], "mno-stackrealign">, Group; +def mrelax : Flag<["-"], "mrelax">, Group, + HelpText<"Enable linker relaxation">; +def mno_relax : Flag<["-"], "mno-relax">, Group, + HelpText<"Disable linker relaxation">; + def munaligned_access : Flag<["-"], "munaligned-access">, Group, HelpText<"Allow memory accesses to be unaligned (AArch32/AArch64 only)">; def mno_unaligned_access : Flag<["-"], "mno-unaligned-access">, Group, Index: cfe/trunk/test/Driver/riscv-features.c === --- cfe/trunk/test/Driver/riscv-features.c +++ cfe/trunk/test/Driver/riscv-features.c @@ -2,3 +2,12 @@ // RUN: %clang -target riscv64-unknown-elf -### %s -fsyntax-only 2>&1 | FileCheck %s // CHECK: fno-signed-char + +// RUN: %clang -target riscv32-unknown-elf -### %s -mrelax 2>&1 | FileCheck %s -check-prefix=RELAX +// RUN: %clang -target riscv32-unknown-elf -### %s -mno-relax 2>&1 | FileCheck %s -check-prefix=NO-RELAX +// RUN: %clang -target riscv32-unknown-elf -### %s 2>&1 | FileCheck %s -check-prefix=DEFAULT + +// RELAX: "-target-feature" "+relax" +// NO-RELAX: "-target-feature" "-relax" +// DEFAULT-NOT: "-target-feature" "+relax" +// DEFAULT-NOT: "-target-feature" "-relax" Index: cfe/trunk/lib/Driver/ToolChains/Arch/RISCV.cpp === --- cfe/trunk/lib/Driver/ToolChains/Arch/RISCV.cpp +++ cfe/trunk/lib/Driver/ToolChains/Arch/RISCV.cpp @@ -15,6 +15,7 @@ #include "llvm/Option/ArgList.h" #include "llvm/Support/TargetParser.h" #include "llvm/Support/raw_ostream.h" +#include "ToolChains/CommonArgs.h" using namespace clang::driver; using namespace clang::driver::tools; @@ -363,6 +364,10 @@ // Handle all other types of extensions. getExtensionFeatures(D, Args, Features, MArch, OtherExts); } + + // Now add any that the user explicitly requested on the command line, + // which may override the defaults. + handleTargetFeaturesGroup(Args, Features, options::OPT_m_riscv_Features_Group); } StringRef riscv::getRISCVABI(const ArgList &Args, const llvm::Triple &Triple) { Index: cfe/trunk/include/clang/Driver/Options.td === --- cfe/trunk/include/clang/Driver/Options.td +++ cfe/trunk/include/clang/Driver/Options.td @@ -151,6 +151,8 @@ Group, DocName<"WebAssembly">; def m_x86_Features_Group : OptionGroup<"">, Group, Flags<[CoreOption]>, DocName<"X86">; +def m_riscv_Features_Group : OptionGroup<"">, + Group, DocName<"RISCV">; def m_libc_Group : OptionGroup<"">, Group, Flags<[HelpHidden]>; @@ -1947,6 +1949,11 @@ def mno_soft_float : Flag<["-"], "mno-soft-float">, Group; def mno_stackrealign : Flag<["-"], "mno-stackrealign">, Group; +def mrelax : Flag<["-"], "mrelax">, Group, + HelpText<"Enable linker relaxation">; +def mno_relax : Flag<["-"], "mno-relax">, Group, + HelpText<"Disable linker relaxation">; + def munaligned_access : Flag<["-"], "munaligned-access">, Group, HelpText<"Allow memory accesses to be unaligned (AArch32/AArch64 only)">; def mno_unaligned_access : Flag<["-"], "mno-unaligned-access">, Group, Index: cfe/trunk/test/Driver/riscv-features.c === --- cfe/trunk/test/Driver/riscv-features.c +++ cfe/trunk/test/Driver/riscv-features.c @@ -2,3 +2,12 @@ // RUN: %clang -target riscv64-unknown-elf -### %s -fsyntax-only 2>&1 | FileCheck %s // CHECK: fno-signed-char + +// RUN: %clang -target riscv32-unknown-elf -### %s -mrelax 2>&1 | FileCheck %s -check-prefix=RELAX +// RUN: %clang -target riscv32-unknown-elf -### %s -mno-relax 2>&1 | FileCheck %s -check-pr
[PATCH] D47476: Support __iso_volatile_load8 etc on aarch64-win32.
This revision was automatically updated to reflect the committed changes. Closed by commit rC333513: Support __iso_volatile_load8 etc on aarch64-win32. (authored by statham, committed by ). Changed prior to commit: https://reviews.llvm.org/D47476?vs=148900&id=149055#toc Repository: rC Clang https://reviews.llvm.org/D47476 Files: include/clang/Basic/BuiltinsAArch64.def lib/CodeGen/CGBuiltin.cpp lib/CodeGen/CodeGenFunction.h test/CodeGen/ms-volatile-aarch64.c Index: include/clang/Basic/BuiltinsAArch64.def === --- include/clang/Basic/BuiltinsAArch64.def +++ include/clang/Basic/BuiltinsAArch64.def @@ -69,5 +69,15 @@ LANGBUILTIN(__dsb, "vUi", "nc", ALL_MS_LANGUAGES) LANGBUILTIN(__isb, "vUi", "nc", ALL_MS_LANGUAGES) +// MSVC intrinsics for volatile but non-acquire/release loads and stores +LANGBUILTIN(__iso_volatile_load8, "ccCD*", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(__iso_volatile_load16, "ssCD*", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(__iso_volatile_load32, "iiCD*", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(__iso_volatile_load64, "LLiLLiCD*", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(__iso_volatile_store8, "vcD*c", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(__iso_volatile_store16, "vsD*s", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(__iso_volatile_store32, "viD*i", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(__iso_volatile_store64, "vLLiD*LLi", "n", ALL_MS_LANGUAGES) + #undef BUILTIN #undef LANGBUILTIN Index: test/CodeGen/ms-volatile-aarch64.c === --- test/CodeGen/ms-volatile-aarch64.c +++ test/CodeGen/ms-volatile-aarch64.c @@ -0,0 +1,13 @@ +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-win32 -emit-llvm -fms-extensions -fms-volatile -o - < %s | FileCheck %s + +void test1(int volatile *p, int v) { + __iso_volatile_store32(p, v); + // CHECK-LABEL: @test1 + // CHECK: store volatile {{.*}}, {{.*}} +} +int test2(const int volatile *p) { + return __iso_volatile_load32(p); + // CHECK-LABEL: @test2 + // CHECK: load volatile {{.*}} +} Index: lib/CodeGen/CGBuiltin.cpp === --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -5179,6 +5179,34 @@ return true; } +Value *CodeGenFunction::EmitISOVolatileLoad(const CallExpr *E) { + Value *Ptr = EmitScalarExpr(E->getArg(0)); + QualType ElTy = E->getArg(0)->getType()->getPointeeType(); + CharUnits LoadSize = getContext().getTypeSizeInChars(ElTy); + llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(), + LoadSize.getQuantity() * 8); + Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo()); + llvm::LoadInst *Load = +Builder.CreateAlignedLoad(Ptr, LoadSize); + Load->setVolatile(true); + return Load; +} + +Value *CodeGenFunction::EmitISOVolatileStore(const CallExpr *E) { + Value *Ptr = EmitScalarExpr(E->getArg(0)); + Value *Value = EmitScalarExpr(E->getArg(1)); + QualType ElTy = E->getArg(0)->getType()->getPointeeType(); + CharUnits StoreSize = getContext().getTypeSizeInChars(ElTy); + llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(), + StoreSize.getQuantity() * 8); + Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo()); + llvm::StoreInst *Store = +Builder.CreateAlignedStore(Value, Ptr, + StoreSize); + Store->setVolatile(true); + return Store; +} + Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, const CallExpr *E, llvm::Triple::ArchType Arch) { @@ -5421,35 +5449,13 @@ case ARM::BI__iso_volatile_load8: case ARM::BI__iso_volatile_load16: case ARM::BI__iso_volatile_load32: - case ARM::BI__iso_volatile_load64: { -Value *Ptr = EmitScalarExpr(E->getArg(0)); -QualType ElTy = E->getArg(0)->getType()->getPointeeType(); -CharUnits LoadSize = getContext().getTypeSizeInChars(ElTy); -llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(), - LoadSize.getQuantity() * 8); -Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo()); -llvm::LoadInst *Load = - Builder.CreateAlignedLoad(Ptr, LoadSize); -Load->setVolatile(true); -return Load; - } + case ARM::BI__iso_volatile_load64: +return EmitISOVolatileLoad(E); case ARM::BI__iso_volatile_store8: case ARM::BI__iso_volatile_store16: case ARM::BI__iso_volatile_store32: - case ARM::BI__iso_volatile_store64: { -Value *Ptr = EmitScalarExpr(E->getArg(0)); -Value *Value = EmitScalarExpr(E->getArg(1)); -QualType ElTy = E->getArg(0)->getType()->getPointeeType(); -CharUnits StoreSize = getContext().getTypeSizeInChars(ElTy); -llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(), - Store
[PATCH] D47476: Support __iso_volatile_load8 etc on aarch64-win32.
This revision was automatically updated to reflect the committed changes. Closed by commit rL333513: Support __iso_volatile_load8 etc on aarch64-win32. (authored by statham, committed by ). Herald added a subscriber: llvm-commits. Repository: rC Clang https://reviews.llvm.org/D47476 Files: cfe/trunk/include/clang/Basic/BuiltinsAArch64.def cfe/trunk/lib/CodeGen/CGBuiltin.cpp cfe/trunk/lib/CodeGen/CodeGenFunction.h cfe/trunk/test/CodeGen/ms-volatile-aarch64.c Index: cfe/trunk/include/clang/Basic/BuiltinsAArch64.def === --- cfe/trunk/include/clang/Basic/BuiltinsAArch64.def +++ cfe/trunk/include/clang/Basic/BuiltinsAArch64.def @@ -69,5 +69,15 @@ LANGBUILTIN(__dsb, "vUi", "nc", ALL_MS_LANGUAGES) LANGBUILTIN(__isb, "vUi", "nc", ALL_MS_LANGUAGES) +// MSVC intrinsics for volatile but non-acquire/release loads and stores +LANGBUILTIN(__iso_volatile_load8, "ccCD*", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(__iso_volatile_load16, "ssCD*", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(__iso_volatile_load32, "iiCD*", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(__iso_volatile_load64, "LLiLLiCD*", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(__iso_volatile_store8, "vcD*c", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(__iso_volatile_store16, "vsD*s", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(__iso_volatile_store32, "viD*i", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(__iso_volatile_store64, "vLLiD*LLi", "n", ALL_MS_LANGUAGES) + #undef BUILTIN #undef LANGBUILTIN Index: cfe/trunk/test/CodeGen/ms-volatile-aarch64.c === --- cfe/trunk/test/CodeGen/ms-volatile-aarch64.c +++ cfe/trunk/test/CodeGen/ms-volatile-aarch64.c @@ -0,0 +1,13 @@ +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-win32 -emit-llvm -fms-extensions -fms-volatile -o - < %s | FileCheck %s + +void test1(int volatile *p, int v) { + __iso_volatile_store32(p, v); + // CHECK-LABEL: @test1 + // CHECK: store volatile {{.*}}, {{.*}} +} +int test2(const int volatile *p) { + return __iso_volatile_load32(p); + // CHECK-LABEL: @test2 + // CHECK: load volatile {{.*}} +} Index: cfe/trunk/lib/CodeGen/CGBuiltin.cpp === --- cfe/trunk/lib/CodeGen/CGBuiltin.cpp +++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp @@ -5179,6 +5179,34 @@ return true; } +Value *CodeGenFunction::EmitISOVolatileLoad(const CallExpr *E) { + Value *Ptr = EmitScalarExpr(E->getArg(0)); + QualType ElTy = E->getArg(0)->getType()->getPointeeType(); + CharUnits LoadSize = getContext().getTypeSizeInChars(ElTy); + llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(), + LoadSize.getQuantity() * 8); + Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo()); + llvm::LoadInst *Load = +Builder.CreateAlignedLoad(Ptr, LoadSize); + Load->setVolatile(true); + return Load; +} + +Value *CodeGenFunction::EmitISOVolatileStore(const CallExpr *E) { + Value *Ptr = EmitScalarExpr(E->getArg(0)); + Value *Value = EmitScalarExpr(E->getArg(1)); + QualType ElTy = E->getArg(0)->getType()->getPointeeType(); + CharUnits StoreSize = getContext().getTypeSizeInChars(ElTy); + llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(), + StoreSize.getQuantity() * 8); + Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo()); + llvm::StoreInst *Store = +Builder.CreateAlignedStore(Value, Ptr, + StoreSize); + Store->setVolatile(true); + return Store; +} + Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, const CallExpr *E, llvm::Triple::ArchType Arch) { @@ -5421,35 +5449,13 @@ case ARM::BI__iso_volatile_load8: case ARM::BI__iso_volatile_load16: case ARM::BI__iso_volatile_load32: - case ARM::BI__iso_volatile_load64: { -Value *Ptr = EmitScalarExpr(E->getArg(0)); -QualType ElTy = E->getArg(0)->getType()->getPointeeType(); -CharUnits LoadSize = getContext().getTypeSizeInChars(ElTy); -llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(), - LoadSize.getQuantity() * 8); -Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo()); -llvm::LoadInst *Load = - Builder.CreateAlignedLoad(Ptr, LoadSize); -Load->setVolatile(true); -return Load; - } + case ARM::BI__iso_volatile_load64: +return EmitISOVolatileLoad(E); case ARM::BI__iso_volatile_store8: case ARM::BI__iso_volatile_store16: case ARM::BI__iso_volatile_store32: - case ARM::BI__iso_volatile_store64: { -Value *Ptr = EmitScalarExpr(E->getArg(0)); -Value *Value = EmitScalarExpr(E->getArg(1)); -QualType ElTy = E->getArg(0)->getType()->getPointeeType(); -CharUnits StoreSize = getContext().getTypeSizeInChars(ElTy); -llvm::Type *ITy = llvm:
[PATCH] D38225: [clangd] Fix missing "message" key when responding with unsupported method
This revision was automatically updated to reflect the committed changes. Closed by commit rL314119: [clangd] Fix missing "message" key when responding with unsupported method (authored by d0k). Repository: rL LLVM https://reviews.llvm.org/D38225 Files: clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp clang-tools-extra/trunk/test/clangd/unsupported-method.test Index: clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp === --- clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp +++ clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp @@ -42,7 +42,7 @@ // Return that this method is unsupported. writeMessage( R"({"jsonrpc":"2.0","id":)" + ID + - R"(,"error":{"code":-32601}})"); + R"(,"error":{"code":-32601,"message":"method not found"}})"); } void Handler::handleNotification(llvm::yaml::MappingNode *Params) { Index: clang-tools-extra/trunk/test/clangd/unsupported-method.test === --- clang-tools-extra/trunk/test/clangd/unsupported-method.test +++ clang-tools-extra/trunk/test/clangd/unsupported-method.test @@ -0,0 +1,19 @@ +# RUN: clangd -run-synchronously < %s | FileCheck %s +# It is absolutely vital that this file has CRLF line endings. +# +Content-Length: 125 + +{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}} + +Content-Length: 143 + +{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":""}}} + +Content-Length: 92 + +{"jsonrpc":"2.0","id":1,"method":"textDocument/jumpInTheAirLikeYouJustDontCare","params":{}} +# CHECK: {"jsonrpc":"2.0","id":1,"error":{"code":-32601,"message":"method not found"}} + +Content-Length: 44 + +{"jsonrpc":"2.0","id":2,"method":"shutdown"} Index: clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp === --- clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp +++ clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp @@ -42,7 +42,7 @@ // Return that this method is unsupported. writeMessage( R"({"jsonrpc":"2.0","id":)" + ID + - R"(,"error":{"code":-32601}})"); + R"(,"error":{"code":-32601,"message":"method not found"}})"); } void Handler::handleNotification(llvm::yaml::MappingNode *Params) { Index: clang-tools-extra/trunk/test/clangd/unsupported-method.test === --- clang-tools-extra/trunk/test/clangd/unsupported-method.test +++ clang-tools-extra/trunk/test/clangd/unsupported-method.test @@ -0,0 +1,19 @@ +# RUN: clangd -run-synchronously < %s | FileCheck %s +# It is absolutely vital that this file has CRLF line endings. +# +Content-Length: 125 + +{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}} + +Content-Length: 143 + +{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":""}}} + +Content-Length: 92 + +{"jsonrpc":"2.0","id":1,"method":"textDocument/jumpInTheAirLikeYouJustDontCare","params":{}} +# CHECK: {"jsonrpc":"2.0","id":1,"error":{"code":-32601,"message":"method not found"}} + +Content-Length: 44 + +{"jsonrpc":"2.0","id":2,"method":"shutdown"} ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D36737: [analyzer] Store design discussions in docs/analyzer for future use.
This revision was automatically updated to reflect the committed changes. Closed by commit rL314218: [analyzer] Keep track of design discusions as part of analyzer documentation. (authored by dergachev). Changed prior to commit: https://reviews.llvm.org/D36737?vs=116520&id=116724#toc Repository: rL LLVM https://reviews.llvm.org/D36737 Files: cfe/trunk/docs/analyzer/DesignDiscussions/InitializerLists.rst Index: cfe/trunk/docs/analyzer/DesignDiscussions/InitializerLists.rst === --- cfe/trunk/docs/analyzer/DesignDiscussions/InitializerLists.rst +++ cfe/trunk/docs/analyzer/DesignDiscussions/InitializerLists.rst @@ -0,0 +1,321 @@ +This discussion took place in https://reviews.llvm.org/D35216 +"Escape symbols when creating std::initializer_list". + +It touches problems of modelling C++ standard library constructs in general, +including modelling implementation-defined fields within C++ standard library +objects, in particular constructing objects into pointers held by such fields, +and separation of responsibilities between analyzer's core and checkers. + +**Artem:** + +I've seen a few false positives that appear because we construct +C++11 std::initializer_list objects with brace initializers, and such +construction is not properly modeled. For instance, if a new object is +constructed on the heap only to be put into a brace-initialized STL container, +the object is reported to be leaked. + +Approach (0): This can be trivially fixed by this patch, which causes pointers +passed into initializer list expressions to immediately escape. + +This fix is overly conservative though. So i did a bit of investigation as to +how model std::initializer_list better. + +According to the standard, std::initializer_list is an object that has +methods begin(), end(), and size(), where begin() returns a pointer to continous +array of size() objects of type T, and end() is equal to begin() plus size(). +The standard does hint that it should be possible to implement +std::initializer_list as a pair of pointers, or as a pointer and a size +integer, however specific fields that the object would contain are an +implementation detail. + +Ideally, we should be able to model the initializer list's methods precisely. +Or, at least, it should be possible to explain to the analyzer that the list +somehow "takes hold" of the values put into it. Initializer lists can also be +copied, which is a separate story that i'm not trying to address here. + +The obvious approach to modeling std::initializer_list in a checker would be to +construct a SymbolMetadata for the memory region of the initializer list object, +which would be of type T* and represent begin(), so we'd trivially model begin() +as a function that returns this symbol. The array pointed to by that symbol +would be bindLoc()ed to contain the list's contents (probably as a CompoundVal +to produce less bindings in the store). Extent of this array would represent +size() and would be equal to the length of the list as written. + +So this sounds good, however apparently it does nothing to address our false +positives: when the list escapes, our RegionStoreManager is not magically +guessing that the metadata symbol attached to it, together with its contents, +should also escape. In fact, it's impossible to trigger a pointer escape from +within the checker. + +Approach (1): If only we enabled ProgramState::bindLoc(..., notifyChanges=true) +to cause pointer escapes (not only region changes) (which sounds like the right +thing to do anyway) such checker would be able to solve the false positives by +triggering escapes when binding list elements to the list. However, it'd be as +conservative as the current patch's solution. Ideally, we do not want escapes to +happen so early. Instead, we'd prefer them to be delayed until the list itself +escapes. + +So i believe that escaping metadata symbols whenever their base regions escape +would be the right thing to do. Currently we didn't think about that because we +had neither pointer-type metadatas nor non-pointer escapes. + +Approach (2): We could teach the Store to scan itself for bindings to +metadata-symbolic-based regions during scanReachableSymbols() whenever a region +turns out to be reachable. This requires no work on checker side, but it sounds +performance-heavy. + +Approach (3): We could let checkers maintain the set of active metadata symbols +in the program state (ideally somewhere in the Store, which sounds weird but +causes the smallest amount of layering violations), so that the core knew what +to escape. This puts a stress on the checkers, but with a smart data map it +wouldn't be a problem. + +Approach (4): We could allow checkers to trigger pointer escapes in arbitrary +moments. If we allow doing this within checkPointerEscape callback itself, we +would be able to express facts like "when this region escapes, that metadata +symbol attached to it should also
[PATCH] D37023: [analyzer] Fix bugreporter::getDerefExpr() again.
This revision was automatically updated to reflect the committed changes. Closed by commit rL314287: [analyzer] Fix and refactor bugreporter::getDerefExpr() API. (authored by dergachev). Changed prior to commit: https://reviews.llvm.org/D37023?vs=116673&id=116781#toc Repository: rL LLVM https://reviews.llvm.org/D37023 Files: cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp cfe/trunk/test/Analysis/null-deref-path-notes.c cfe/trunk/test/Analysis/null-deref-path-notes.cpp cfe/trunk/test/Analysis/null-deref-path-notes.m Index: cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp === --- cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -42,48 +42,68 @@ return false; } +/// Given that expression S represents a pointer that would be dereferenced, +/// try to find a sub-expression from which the pointer came from. +/// This is used for tracking down origins of a null or undefined value: +/// "this is null because that is null because that is null" etc. +/// We wipe away field and element offsets because they merely add offsets. +/// We also wipe away all casts except lvalue-to-rvalue casts, because the +/// latter represent an actual pointer dereference; however, we remove +/// the final lvalue-to-rvalue cast before returning from this function +/// because it demonstrates more clearly from where the pointer rvalue was +/// loaded. Examples: +/// x->y.z ==> x (lvalue) +/// foo()->y.z ==> foo() (rvalue) const Expr *bugreporter::getDerefExpr(const Stmt *S) { - // Pattern match for a few useful cases: - // a[0], p->f, *p const Expr *E = dyn_cast(S); if (!E) return nullptr; - E = E->IgnoreParenCasts(); while (true) { -if (const BinaryOperator *B = dyn_cast(E)) { - assert(B->isAssignmentOp()); - E = B->getLHS()->IgnoreParenCasts(); - continue; -} -else if (const UnaryOperator *U = dyn_cast(E)) { - if (U->getOpcode() == UO_Deref) -return U->getSubExpr()->IgnoreParenCasts(); -} -else if (const MemberExpr *ME = dyn_cast(E)) { - if (ME->isImplicitAccess()) { -return ME; - } else if (ME->isArrow() || isDeclRefExprToReference(ME->getBase())) { -return ME->getBase()->IgnoreParenCasts(); +if (const CastExpr *CE = dyn_cast(E)) { + if (CE->getCastKind() == CK_LValueToRValue) { +// This cast represents the load we're looking for. +break; + } + E = CE->getSubExpr(); +} else if (isa(E)) { + // Probably more arithmetic can be pattern-matched here, + // but for now give up. + break; +} else if (const UnaryOperator *U = dyn_cast(E)) { + if (U->getOpcode() == UO_Deref) { +// Operators '*' and '&' don't actually mean anything. +// We look at casts instead. +E = U->getSubExpr(); } else { -// If we have a member expr with a dot, the base must have been -// dereferenced. -return getDerefExpr(ME->getBase()); +// Probably more arithmetic can be pattern-matched here, +// but for now give up. +break; } } -else if (const ObjCIvarRefExpr *IvarRef = dyn_cast(E)) { - return IvarRef->getBase()->IgnoreParenCasts(); -} -else if (const ArraySubscriptExpr *AE = dyn_cast(E)) { - return getDerefExpr(AE->getBase()); -} -else if (isa(E)) { - return E; +// Pattern match for a few useful cases: a[0], p->f, *p etc. +else if (const MemberExpr *ME = dyn_cast(E)) { + E = ME->getBase(); +} else if (const ObjCIvarRefExpr *IvarRef = dyn_cast(E)) { + E = IvarRef->getBase(); +} else if (const ArraySubscriptExpr *AE = dyn_cast(E)) { + E = AE->getBase(); +} else if (const ParenExpr *PE = dyn_cast(E)) { + E = PE->getSubExpr(); +} else { + // Other arbitrary stuff. + break; } -break; } - return nullptr; + // Special case: remove the final lvalue-to-rvalue cast, but do not recurse + // deeper into the sub-expression. This way we return the lvalue from which + // our pointer rvalue was loaded. + if (const ImplicitCastExpr *CE = dyn_cast(E)) +if (CE->getCastKind() == CK_LValueToRValue) + E = CE->getSubExpr(); + + return E; } const Stmt *bugreporter::GetDenomExpr(const ExplodedNode *N) { Index: cfe/trunk/test/Analysis/null-deref-path-notes.m === --- cfe/trunk/test/Analysis/null-deref-path-notes.m +++ cfe/trunk/test/Analysis/null-deref-path-notes.m @@ -50,6 +50,23 @@ *p = 1; // expected-warning{{Dereference of null pointer}} expected-note{{Dereference of null pointer}} } +@interface WithArrayPtr +- (void) useArray; +@end + +@implementation WithArrayPtr { +@public int *p; +} +- (void)useArray { + p[1] = 2; // expected-warning{{Array access (via ivar 'p') res
[PATCH] D37025: [analyzer] Support more pointer arithmetic in bugreporter::getDerefExpr().
This revision was automatically updated to reflect the committed changes. Closed by commit rL314290: [analyzer] Match more patterns in bugreporter::getDerefExpr() API. (authored by dergachev). Changed prior to commit: https://reviews.llvm.org/D37025?vs=112221&id=116783#toc Repository: rL LLVM https://reviews.llvm.org/D37025 Files: cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp cfe/trunk/test/Analysis/inlining/inline-defensive-checks.c cfe/trunk/test/Analysis/null-deref-path-notes.c cfe/trunk/test/Analysis/nullptr.cpp Index: cfe/trunk/test/Analysis/null-deref-path-notes.c === --- cfe/trunk/test/Analysis/null-deref-path-notes.c +++ cfe/trunk/test/Analysis/null-deref-path-notes.c @@ -4,7 +4,7 @@ // of the null pointer for path notes. Apparently, not much actual tracking // needs to be done in this example. void pr34373() { - int *a = 0; + int *a = 0; // expected-note{{'a' initialized to a null pointer value}} (a + 0)[0]; // expected-warning{{Array access results in a null pointer dereference}} // expected-note@-1{{Array access results in a null pointer dereference}} } Index: cfe/trunk/test/Analysis/inlining/inline-defensive-checks.c === --- cfe/trunk/test/Analysis/inlining/inline-defensive-checks.c +++ cfe/trunk/test/Analysis/inlining/inline-defensive-checks.c @@ -169,6 +169,18 @@ *x = 7; // no-warning } +void idcTrackZeroValueThroughManyUnaryPointerOperatorsWithAssignment(struct S *s) { + idc(s); + int *x = &*&(s->f1); + *x = 7; // no-warning +} + +void idcTrackZeroValueThroughManyUnaryPointerOperatorsWithAssignmentAndUnaryIncrement(struct S *s) { + idc(s); + int *x = &*&((++s)->f1); + *x = 7; // no-warning +} + struct S2 { int a[1]; Index: cfe/trunk/test/Analysis/nullptr.cpp === --- cfe/trunk/test/Analysis/nullptr.cpp +++ cfe/trunk/test/Analysis/nullptr.cpp @@ -1,11 +1,12 @@ -// RUN: %clang_analyze_cc1 -std=c++11 -Wno-conversion-null -analyzer-checker=core,debug.ExprInspection -analyzer-store region -verify %s +// RUN: %clang_analyze_cc1 -std=c++11 -Wno-conversion-null -analyzer-checker=core,debug.ExprInspection -analyzer-store region -analyzer-output=text -verify %s void clang_analyzer_eval(int); // test to see if nullptr is detected as a null pointer void foo1(void) { - char *np = nullptr; + char *np = nullptr; // expected-note{{'np' initialized to a null pointer value}} *np = 0; // expected-warning{{Dereference of null pointer}} +// expected-note@-1{{Dereference of null pointer}} } // check if comparing nullptr to nullptr is detected properly @@ -23,10 +24,11 @@ struct foo { int a, f; }; - char *np = nullptr; + char *np = nullptr; // expected-note{{'np' initialized to a null pointer value}} // casting a nullptr to anything should be caught eventually - int *ip = &(((struct foo *)np)->f); + int *ip = &(((struct foo *)np)->f); // expected-note{{'ip' initialized to a null pointer value}} *ip = 0; // expected-warning{{Dereference of null pointer}} +// expected-note@-1{{Dereference of null pointer}} // should be error here too, but analysis gets stopped // *np = 0; } @@ -49,16 +51,31 @@ } void zoo1() { - char **p = 0; + char **p = 0; // expected-note{{'p' initialized to a null pointer value}} delete *(p + 0); // expected-warning{{Dereference of null pointer}} + // expected-note@-1{{Dereference of null pointer}} +} + +void zoo1backwards() { + char **p = 0; // expected-note{{'p' initialized to a null pointer value}} + delete *(0 + p); // expected-warning{{Dereference of null pointer}} + // expected-note@-1{{Dereference of null pointer}} +} + +typedef __INTPTR_TYPE__ intptr_t; +void zoo1multiply() { + char **p = 0; // FIXME-should-be-note:{{'p' initialized to a null pointer value}} + delete *((char **)((intptr_t)p * 2)); // expected-warning{{Dereference of null pointer}} + // expected-note@-1{{Dereference of null pointer}} } void zoo2() { int **a = 0; - int **b = 0; + int **b = 0; // expected-note{{'b' initialized to a null pointer value}} asm ("nop" :"=r"(*a) :"0"(*b) // expected-warning{{Dereference of null pointer}} + // expected-note@-1{{Dereference of null pointer}} ); } @@ -70,17 +87,19 @@ int a; }; - int *x = 0; + int *x = 0; // expected-note{{'x' initialized to a null pointer value}} return S(*x).a; // expected-warning{{Dereference of null pointer}} + // expected-note@-1{{Dereference of null pointer}} } int materializeTempExpr() { - int *n = 0; + int *n = 0; // expected-note{{'n' initialized to a null pointer value}} struct S { int a; S(int i): a(i) {} }; const S &s = S(*n); // expected-warning{{Dereferenc
[PATCH] D37804: [OpenCL] Handle address space conversion while setting type alignment
This revision was automatically updated to reflect the committed changes. Closed by commit rL314304: [OpenCL] Handle address space conversion while setting type alignment. (authored by stulova). Changed prior to commit: https://reviews.llvm.org/D37804?vs=116548&id=116809#toc Repository: rL LLVM https://reviews.llvm.org/D37804 Files: cfe/trunk/lib/CodeGen/CGBuilder.h cfe/trunk/lib/CodeGen/CGExpr.cpp cfe/trunk/test/CodeGenOpenCL/vectorLoadStore.cl Index: cfe/trunk/lib/CodeGen/CGBuilder.h === --- cfe/trunk/lib/CodeGen/CGBuilder.h +++ cfe/trunk/lib/CodeGen/CGBuilder.h @@ -145,6 +145,13 @@ Addr.getAlignment()); } + using CGBuilderBaseTy::CreateAddrSpaceCast; + Address CreateAddrSpaceCast(Address Addr, llvm::Type *Ty, + const llvm::Twine &Name = "") { +return Address(CreateAddrSpaceCast(Addr.getPointer(), Ty, Name), + Addr.getAlignment()); + } + /// Cast the element type of the given address to a different type, /// preserving information like the alignment and address space. Address CreateElementBitCast(Address Addr, llvm::Type *Ty, Index: cfe/trunk/lib/CodeGen/CGExpr.cpp === --- cfe/trunk/lib/CodeGen/CGExpr.cpp +++ cfe/trunk/lib/CodeGen/CGExpr.cpp @@ -925,6 +925,7 @@ // Non-converting casts (but not C's implicit conversion from void*). case CK_BitCast: case CK_NoOp: +case CK_AddressSpaceConversion: if (auto PtrTy = CE->getSubExpr()->getType()->getAs()) { if (PtrTy->getPointeeType()->isVoidType()) break; @@ -953,8 +954,10 @@ CodeGenFunction::CFITCK_UnrelatedCast, CE->getLocStart()); } - -return Builder.CreateBitCast(Addr, ConvertType(E->getType())); +return CE->getCastKind() != CK_AddressSpaceConversion + ? Builder.CreateBitCast(Addr, ConvertType(E->getType())) + : Builder.CreateAddrSpaceCast(Addr, + ConvertType(E->getType())); } break; Index: cfe/trunk/test/CodeGenOpenCL/vectorLoadStore.cl === --- cfe/trunk/test/CodeGenOpenCL/vectorLoadStore.cl +++ cfe/trunk/test/CodeGenOpenCL/vectorLoadStore.cl @@ -1,9 +1,22 @@ -// RUN: %clang_cc1 %s -emit-llvm -O0 -o - | FileCheck %s +// RUN: %clang_cc1 -triple "spir-unknown-unknown" %s -emit-llvm -O0 -o - | FileCheck %s -typedef char char3 __attribute((ext_vector_type(3)));; +typedef char char2 __attribute((ext_vector_type(2))); +typedef char char3 __attribute((ext_vector_type(3))); +typedef char char8 __attribute((ext_vector_type(8))); +typedef float float4 __attribute((ext_vector_type(4))); // Check for optimized vec3 load/store which treats vec3 as vec4. void foo(char3 *P, char3 *Q) { *P = *Q; // CHECK: %{{.*}} = shufflevector <4 x i8> %{{.*}}, <4 x i8> undef, <3 x i32> } + +// CHECK: define spir_func void @alignment() +void alignment() { + __private char2 data_generic[100]; + __private char8 data_private[100]; + + // CHECK: %{{.*}} = load <4 x float>, <4 x float> addrspace(4)* %{{.*}}, align 2 + // CHECK: store <4 x float> %{{.*}}, <4 x float>* %{{.*}}, align 8 + ((private float4 *)data_private)[1] = ((float4 *)data_generic)[2]; +} Index: cfe/trunk/lib/CodeGen/CGBuilder.h === --- cfe/trunk/lib/CodeGen/CGBuilder.h +++ cfe/trunk/lib/CodeGen/CGBuilder.h @@ -145,6 +145,13 @@ Addr.getAlignment()); } + using CGBuilderBaseTy::CreateAddrSpaceCast; + Address CreateAddrSpaceCast(Address Addr, llvm::Type *Ty, + const llvm::Twine &Name = "") { +return Address(CreateAddrSpaceCast(Addr.getPointer(), Ty, Name), + Addr.getAlignment()); + } + /// Cast the element type of the given address to a different type, /// preserving information like the alignment and address space. Address CreateElementBitCast(Address Addr, llvm::Type *Ty, Index: cfe/trunk/lib/CodeGen/CGExpr.cpp === --- cfe/trunk/lib/CodeGen/CGExpr.cpp +++ cfe/trunk/lib/CodeGen/CGExpr.cpp @@ -925,6 +925,7 @@ // Non-converting casts (but not C's implicit conversion from void*). case CK_BitCast: case CK_NoOp: +case CK_AddressSpaceConversion: if (auto PtrTy = CE->getSubExpr()->getType()->getAs()) { if (PtrTy->getPointeeType()->isVoidType()) break; @@ -953,8 +954,10 @@ CodeGenFunction::CFITCK_UnrelatedCast, CE->getLocStart()); } - -return Builder.CreateBitCast(Addr, ConvertType(E->getType())); +return CE->getCastKin
[PATCH] D38083: [clangd] Skip informative qualifier chunks.
This revision was automatically updated to reflect the committed changes. Closed by commit rL314445: [clangd] Skip informative qualifier chunks. (authored by ibiryukov). Repository: rL LLVM https://reviews.llvm.org/D38083 Files: clang-tools-extra/trunk/clangd/ClangdUnit.cpp clang-tools-extra/trunk/test/clangd/completion-qualifiers.test Index: clang-tools-extra/trunk/clangd/ClangdUnit.cpp === --- clang-tools-extra/trunk/clangd/ClangdUnit.cpp +++ clang-tools-extra/trunk/clangd/ClangdUnit.cpp @@ -409,6 +409,11 @@ }; // CompletionItemsCollector +bool isInformativeQualifierChunk(CodeCompletionString::Chunk const &Chunk) { + return Chunk.Kind == CodeCompletionString::CK_Informative && + StringRef(Chunk.Text).endswith("::"); +} + class PlainTextCompletionItemsCollector final : public CompletionItemsCollector { @@ -421,6 +426,11 @@ void ProcessChunks(const CodeCompletionString &CCS, CompletionItem &Item) const override { for (const auto &Chunk : CCS) { + // Informative qualifier chunks only clutter completion results, skip + // them. + if (isInformativeQualifierChunk(Chunk)) +continue; + switch (Chunk.Kind) { case CodeCompletionString::CK_TypedText: // There's always exactly one CK_TypedText chunk. @@ -453,6 +463,11 @@ CompletionItem &Item) const override { unsigned ArgCount = 0; for (const auto &Chunk : CCS) { + // Informative qualifier chunks only clutter completion results, skip + // them. + if (isInformativeQualifierChunk(Chunk)) +continue; + switch (Chunk.Kind) { case CodeCompletionString::CK_TypedText: // The piece of text that the user is expected to type to match Index: clang-tools-extra/trunk/test/clangd/completion-qualifiers.test === --- clang-tools-extra/trunk/test/clangd/completion-qualifiers.test +++ clang-tools-extra/trunk/test/clangd/completion-qualifiers.test @@ -0,0 +1,18 @@ +# RUN: clangd -run-synchronously < %s | FileCheck %s +Content-Length: 125 + +{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}} +Content-Length: 297 + +{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"class Foo {\n public:\nint foo() const;\nint bar() const;\n};\n\nclass Bar : public Foo {\n int foo() const;\n};\n\nvoid test() {\n Bar().\n}"}}} +Content-Length: 151 + +{"jsonrpc":"2.0","id":2,"method":"textDocument/completion","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":11,"character":8}}} +# CHECK: {"jsonrpc":"2.0","id":2,"result":[ +# CHECK-DAG: {"label":"foo() const","kind":2,"detail":"int","sortText":"200035foo","filterText":"foo","insertText":"foo","insertTextFormat":1} +# CHECK-DAG: {"label":"bar() const","kind":2,"detail":"int","sortText":"37bar","filterText":"bar","insertText":"bar","insertTextFormat":1} +# CHECK-DAG: {"label":"Foo::foo() const","kind":2,"detail":"int","sortText":"37foo","filterText":"foo","insertText":"foo","insertTextFormat":1} +# CHECK: ]} +Content-Length: 44 + +{"jsonrpc":"2.0","id":4,"method":"shutdown"} Index: clang-tools-extra/trunk/clangd/ClangdUnit.cpp === --- clang-tools-extra/trunk/clangd/ClangdUnit.cpp +++ clang-tools-extra/trunk/clangd/ClangdUnit.cpp @@ -409,6 +409,11 @@ }; // CompletionItemsCollector +bool isInformativeQualifierChunk(CodeCompletionString::Chunk const &Chunk) { + return Chunk.Kind == CodeCompletionString::CK_Informative && + StringRef(Chunk.Text).endswith("::"); +} + class PlainTextCompletionItemsCollector final : public CompletionItemsCollector { @@ -421,6 +426,11 @@ void ProcessChunks(const CodeCompletionString &CCS, CompletionItem &Item) const override { for (const auto &Chunk : CCS) { + // Informative qualifier chunks only clutter completion results, skip + // them. + if (isInformativeQualifierChunk(Chunk)) +continue; + switch (Chunk.Kind) { case CodeCompletionString::CK_TypedText: // There's always exactly one CK_TypedText chunk. @@ -453,6 +463,11 @@ CompletionItem &Item) const override { unsigned ArgCount = 0; for (const auto &Chunk : CCS) { + // Informative qualifier chunks only clutter completion results, skip + // them. + if (isInformativeQualifierChunk(Chunk)) +continue; + switch (Chunk.Kind) { case CodeCompletionString::CK_TypedText: // The piece of text that the user is expected to type to match Index: clang-tools-extra/trunk/test/clangd/completion-qualifiers.test ==
[PATCH] D37150: [clangd] Command line arg to specify compile_commands.json path
This revision was automatically updated to reflect the committed changes. Closed by commit rL314678: [clangd] Command line arg to specify compile_commands.json path (authored by ibiryukov). Changed prior to commit: https://reviews.llvm.org/D37150?vs=117340&id=117354#toc Repository: rL LLVM https://reviews.llvm.org/D37150 Files: clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp clang-tools-extra/trunk/clangd/ClangdLSPServer.h clang-tools-extra/trunk/clangd/GlobalCompilationDatabase.cpp clang-tools-extra/trunk/clangd/GlobalCompilationDatabase.h clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp Index: clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp === --- clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp +++ clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp @@ -196,8 +196,9 @@ ClangdLSPServer::ClangdLSPServer(JSONOutput &Out, unsigned AsyncThreadsCount, bool SnippetCompletions, - llvm::Optional ResourceDir) -: Out(Out), CDB(/*Logger=*/Out), + llvm::Optional ResourceDir, + llvm::Optional CompileCommandsDir) +: Out(Out), CDB(/*Logger=*/Out, std::move(CompileCommandsDir)), Server(CDB, /*DiagConsumer=*/*this, FSProvider, AsyncThreadsCount, SnippetCompletions, /*Logger=*/Out, ResourceDir) {} Index: clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp === --- clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp +++ clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp @@ -11,16 +11,22 @@ #include "JSONRPCDispatcher.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" #include "llvm/Support/Program.h" - #include #include #include #include using namespace clang; using namespace clang::clangd; +static llvm::cl::opt CompileCommandsDir( +"compile-commands-dir", +llvm::cl::desc("Specify a path to look for compile_commands.json. If path " + "is invalid, clangd will look in the current directory and " + "parent paths of each source file.")); + static llvm::cl::opt WorkerThreadsCount("j", llvm::cl::desc("Number of async workers used by clangd"), @@ -56,18 +62,37 @@ if (RunSynchronously) WorkerThreadsCount = 0; + /// Validate command line arguments. llvm::raw_ostream &Outs = llvm::outs(); llvm::raw_ostream &Logs = llvm::errs(); JSONOutput Out(Outs, Logs); - // Change stdin to binary to not lose \r\n on windows. - llvm::sys::ChangeStdinToBinary(); + // If --compile-commands-dir arg was invoked, check value and override default + // path. + namespace path = llvm::sys::path; + llvm::Optional CompileCommandsDirPath; + + if (CompileCommandsDir.empty()) { +CompileCommandsDirPath = llvm::None; + } else if (!llvm::sys::path::is_absolute(CompileCommandsDir) || + !llvm::sys::fs::exists(CompileCommandsDir)) { +llvm::errs() << "Path specified by --compile-commands-dir either does not " +"exist or is not an absolute " +"path. The argument will be ignored.\n"; +CompileCommandsDirPath = llvm::None; + } else { +CompileCommandsDirPath = CompileCommandsDir; + } llvm::Optional ResourceDirRef = None; if (!ResourceDir.empty()) ResourceDirRef = ResourceDir; + /// Change stdin to binary to not lose \r\n on windows. + llvm::sys::ChangeStdinToBinary(); + + /// Initialize and run ClangdLSPServer. ClangdLSPServer LSPServer(Out, WorkerThreadsCount, EnableSnippets, -ResourceDirRef); +ResourceDirRef, CompileCommandsDirPath); LSPServer.run(std::cin); } Index: clang-tools-extra/trunk/clangd/GlobalCompilationDatabase.h === --- clang-tools-extra/trunk/clangd/GlobalCompilationDatabase.h +++ clang-tools-extra/trunk/clangd/GlobalCompilationDatabase.h @@ -47,15 +47,17 @@ class DirectoryBasedGlobalCompilationDatabase : public GlobalCompilationDatabase { public: - DirectoryBasedGlobalCompilationDatabase(clangd::Logger &Logger); + DirectoryBasedGlobalCompilationDatabase( + clangd::Logger &Logger, llvm::Optional CompileCommandsDir); std::vector getCompileCommands(PathRef File) override; void setExtraFlagsForFile(PathRef File, std::vector ExtraFlags); private: tooling::CompilationDatabase *getCompilationDatabase(PathRef File); + tooling::CompilationDatabase *tryLoadDatabaseFromPath(PathRef File); std::mutex Mutex; /// Caches compilation databases loaded from directories(keys are @@ -67,6 +69,9 @@ llvm::StringMap> ExtraFlagsForFile; /// Used for logging. clangd::Logger &Logger; + /// Used for command argument pointing to fo
[PATCH] D37544: [ubsan] Skip alignment checks which are folded away
This revision was automatically updated to reflect the committed changes. Closed by commit rL314752: [ubsan] Skip alignment checks which are folded away (authored by vedantk). Changed prior to commit: https://reviews.llvm.org/D37544?vs=116374&id=117461#toc Repository: rL LLVM https://reviews.llvm.org/D37544 Files: cfe/trunk/lib/CodeGen/CGExpr.cpp cfe/trunk/test/CodeGenCXX/ubsan-suppress-checks.cpp Index: cfe/trunk/lib/CodeGen/CGExpr.cpp === --- cfe/trunk/lib/CodeGen/CGExpr.cpp +++ cfe/trunk/lib/CodeGen/CGExpr.cpp @@ -618,6 +618,7 @@ auto PtrToAlloca = dyn_cast(Ptr->stripPointerCastsNoFollowAliases()); + llvm::Value *True = llvm::ConstantInt::getTrue(getLLVMContext()); llvm::Value *IsNonNull = nullptr; bool IsGuaranteedNonNull = SkippedChecks.has(SanitizerKind::Null) || PtrToAlloca; @@ -629,8 +630,7 @@ // The IR builder can constant-fold the null check if the pointer points to // a constant. -IsGuaranteedNonNull = -IsNonNull == llvm::ConstantInt::getTrue(getLLVMContext()); +IsGuaranteedNonNull = IsNonNull == True; // Skip the null check if the pointer is known to be non-null. if (!IsGuaranteedNonNull) { @@ -684,7 +684,8 @@ PtrAsInt, llvm::ConstantInt::get(IntPtrTy, AlignVal - 1)); llvm::Value *Aligned = Builder.CreateICmpEQ(Align, llvm::ConstantInt::get(IntPtrTy, 0)); - Checks.push_back(std::make_pair(Aligned, SanitizerKind::Alignment)); + if (Aligned != True) +Checks.push_back(std::make_pair(Aligned, SanitizerKind::Alignment)); } } Index: cfe/trunk/test/CodeGenCXX/ubsan-suppress-checks.cpp === --- cfe/trunk/test/CodeGenCXX/ubsan-suppress-checks.cpp +++ cfe/trunk/test/CodeGenCXX/ubsan-suppress-checks.cpp @@ -17,6 +17,17 @@ // CHECK: ret void } +// CHECK-LABEL: define void @_Z31use_us16_aligned_array_elementsv +void use_us16_aligned_array_elements() { + static const unsigned short Arr[] = {0, 1, 2}; + auto use_array = [](const unsigned short(&X)[3]) -> void {}; + use_array(Arr); + + // CHECK-NOT: br i1 true + // ALIGN-NOT: call void @__ubsan_handle_type_mismatch + // CHECK: ret void +} + struct A { int foo; @@ -229,4 +240,5 @@ d->load_member_3(); load_non_null_pointers(); + use_us16_aligned_array_elements(); } Index: cfe/trunk/lib/CodeGen/CGExpr.cpp === --- cfe/trunk/lib/CodeGen/CGExpr.cpp +++ cfe/trunk/lib/CodeGen/CGExpr.cpp @@ -618,6 +618,7 @@ auto PtrToAlloca = dyn_cast(Ptr->stripPointerCastsNoFollowAliases()); + llvm::Value *True = llvm::ConstantInt::getTrue(getLLVMContext()); llvm::Value *IsNonNull = nullptr; bool IsGuaranteedNonNull = SkippedChecks.has(SanitizerKind::Null) || PtrToAlloca; @@ -629,8 +630,7 @@ // The IR builder can constant-fold the null check if the pointer points to // a constant. -IsGuaranteedNonNull = -IsNonNull == llvm::ConstantInt::getTrue(getLLVMContext()); +IsGuaranteedNonNull = IsNonNull == True; // Skip the null check if the pointer is known to be non-null. if (!IsGuaranteedNonNull) { @@ -684,7 +684,8 @@ PtrAsInt, llvm::ConstantInt::get(IntPtrTy, AlignVal - 1)); llvm::Value *Aligned = Builder.CreateICmpEQ(Align, llvm::ConstantInt::get(IntPtrTy, 0)); - Checks.push_back(std::make_pair(Aligned, SanitizerKind::Alignment)); + if (Aligned != True) +Checks.push_back(std::make_pair(Aligned, SanitizerKind::Alignment)); } } Index: cfe/trunk/test/CodeGenCXX/ubsan-suppress-checks.cpp === --- cfe/trunk/test/CodeGenCXX/ubsan-suppress-checks.cpp +++ cfe/trunk/test/CodeGenCXX/ubsan-suppress-checks.cpp @@ -17,6 +17,17 @@ // CHECK: ret void } +// CHECK-LABEL: define void @_Z31use_us16_aligned_array_elementsv +void use_us16_aligned_array_elements() { + static const unsigned short Arr[] = {0, 1, 2}; + auto use_array = [](const unsigned short(&X)[3]) -> void {}; + use_array(Arr); + + // CHECK-NOT: br i1 true + // ALIGN-NOT: call void @__ubsan_handle_type_mismatch + // CHECK: ret void +} + struct A { int foo; @@ -229,4 +240,5 @@ d->load_member_3(); load_non_null_pointers(); + use_us16_aligned_array_elements(); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38483: [ExprConstant] Allow constexpr ctor to modify non static data members in body
This revision was automatically updated to reflect the committed changes. Closed by commit rL314865: [ExprConstant] Allow constexpr ctor to modify non static data members (authored by epilk). Changed prior to commit: https://reviews.llvm.org/D38483?vs=117529&id=117605#toc Repository: rL LLVM https://reviews.llvm.org/D38483 Files: cfe/trunk/lib/AST/ExprConstant.cpp cfe/trunk/test/SemaCXX/constant-expression-cxx1y.cpp Index: cfe/trunk/test/SemaCXX/constant-expression-cxx1y.cpp === --- cfe/trunk/test/SemaCXX/constant-expression-cxx1y.cpp +++ cfe/trunk/test/SemaCXX/constant-expression-cxx1y.cpp @@ -988,3 +988,36 @@ void(); } constexpr int void_test = (Void(0), 1); + +namespace PR19741 { +constexpr void addone(int &m) { m++; } + +struct S { + int m = 0; + constexpr S() { addone(m); } +}; +constexpr bool evalS() { + constexpr S s; + return s.m == 1; +} +static_assert(evalS(), ""); + +struct Nested { + struct First { int x = 42; }; + union { +First first; +int second; + }; + int x; + constexpr Nested(int x) : first(), x(x) { x = 4; } + constexpr Nested() : Nested(42) { +addone(first.x); +x = 3; + } +}; +constexpr bool evalNested() { + constexpr Nested N; + return N.first.x == 43; +} +static_assert(evalNested(), ""); +} // namespace PR19741 Index: cfe/trunk/lib/AST/ExprConstant.cpp === --- cfe/trunk/lib/AST/ExprConstant.cpp +++ cfe/trunk/lib/AST/ExprConstant.cpp @@ -573,6 +573,31 @@ /// declaration whose initializer is being evaluated, if any. APValue *EvaluatingDeclValue; +/// EvaluatingObject - Pair of the AST node that an lvalue represents and +/// the call index that that lvalue was allocated in. +typedef std::pair EvaluatingObject; + +/// EvaluatingConstructors - Set of objects that are currently being +/// constructed. +llvm::DenseSet EvaluatingConstructors; + +struct EvaluatingConstructorRAII { + EvalInfo &EI; + EvaluatingObject Object; + bool DidInsert; + EvaluatingConstructorRAII(EvalInfo &EI, EvaluatingObject Object) + : EI(EI), Object(Object) { +DidInsert = EI.EvaluatingConstructors.insert(Object).second; + } + ~EvaluatingConstructorRAII() { +if (DidInsert) EI.EvaluatingConstructors.erase(Object); + } +}; + +bool isEvaluatingConstructor(APValue::LValueBase Decl, unsigned CallIndex) { + return EvaluatingConstructors.count(EvaluatingObject(Decl, CallIndex)); +} + /// The current array initialization index, if we're performing array /// initialization. uint64_t ArrayInitIndex = -1; @@ -666,6 +691,7 @@ void setEvaluatingDecl(APValue::LValueBase Base, APValue &Value) { EvaluatingDecl = Base; EvaluatingDeclValue = &Value; + EvaluatingConstructors.insert({Base, 0}); } const LangOptions &getLangOpts() const { return Ctx.getLangOpts(); } @@ -3098,10 +3124,9 @@ } // During the construction of an object, it is not yet 'const'. - // FIXME: We don't set up EvaluatingDecl for local variables or temporaries, - // and this doesn't do quite the right thing for const subobjects of the + // FIXME: This doesn't do quite the right thing for const subobjects of the // object under construction. - if (LVal.getLValueBase() == Info.EvaluatingDecl) { + if (Info.isEvaluatingConstructor(LVal.getLValueBase(), LVal.CallIndex)) { BaseType = Info.Ctx.getCanonicalType(BaseType); BaseType.removeLocalConst(); } @@ -4254,6 +4279,8 @@ return false; } + EvalInfo::EvaluatingConstructorRAII EvalObj( + Info, {This.getLValueBase(), This.CallIndex}); CallStackFrame Frame(Info, CallLoc, Definition, &This, ArgValues); // FIXME: Creating an APValue just to hold a nonexistent return value is ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38358: [analyzer] Fix autodetection of getSVal()'s type argument.
This revision was automatically updated to reflect the committed changes. Closed by commit rL314910: [analyzer] Fix autodetection of binding types. (authored by dergachev). Changed prior to commit: https://reviews.llvm.org/D38358?vs=117360&id=117681#toc Repository: rL LLVM https://reviews.llvm.org/D38358 Files: cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp cfe/trunk/test/Analysis/ctor.mm cfe/trunk/test/Analysis/exercise-ps.c cfe/trunk/test/Analysis/gtest.cpp Index: cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp === --- cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp +++ cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -1393,16 +1393,19 @@ return UnknownVal(); } - if (isa(MR) || - isa(MR) || - isa(MR)) { + if (!isa(MR)) { if (T.isNull()) { if (const TypedRegion *TR = dyn_cast(MR)) -T = TR->getLocationType(); - else { -const SymbolicRegion *SR = cast(MR); -T = SR->getSymbol()->getType(); - } +T = TR->getLocationType()->getPointeeType(); + else if (const SymbolicRegion *SR = dyn_cast(MR)) +T = SR->getSymbol()->getType()->getPointeeType(); + else if (isa(MR)) +T = Ctx.VoidTy; +} +assert(!T.isNull() && "Unable to auto-detect binding type!"); +if (T->isVoidType()) { + // When trying to dereference a void pointer, read the first byte. + T = Ctx.CharTy; } MR = GetElementZeroRegion(cast(MR), T); } Index: cfe/trunk/test/Analysis/ctor.mm === --- cfe/trunk/test/Analysis/ctor.mm +++ cfe/trunk/test/Analysis/ctor.mm @@ -199,7 +199,7 @@ Inner p; }; - void testPOD() { + void testPOD(const POD &pp) { POD p; p.x = 1; POD p2 = p; // no-warning @@ -210,6 +210,15 @@ // Use rvalues as well. clang_analyzer_eval(POD(p3).x == 1); // expected-warning{{TRUE}} +// Copy from symbolic references correctly. +POD p4 = pp; +// Make sure that p4.x contains a symbol after copy. +if (p4.x > 0) + clang_analyzer_eval(p4.x > 0); // expected-warning{{TRUE}} +// FIXME: Element region gets in the way, so these aren't the same symbols +// as they should be. +clang_analyzer_eval(pp.x == p4.x); // expected-warning{{UNKNOWN}} + PODWrapper w; w.p.y = 1; PODWrapper w2 = w; // no-warning Index: cfe/trunk/test/Analysis/exercise-ps.c === --- cfe/trunk/test/Analysis/exercise-ps.c +++ cfe/trunk/test/Analysis/exercise-ps.c @@ -21,3 +21,11 @@ memcpy((&x[1]), (buf), 1); // expected-warning{{implicitly declaring library function 'memcpy' with type 'void *(void *, const void *}} \ // expected-note{{include the header or explicitly provide a declaration for 'memcpy'}} } + +// AllocaRegion is untyped. Void pointer isn't of much help either. Before +// realizing that the value is undefined, we need to somehow figure out +// what type of value do we expect. +void f3(void *dest) { + void *src = __builtin_alloca(5); + memcpy(dest, src, 1); // expected-warning{{2nd function call argument is a pointer to uninitialized value}} +} Index: cfe/trunk/test/Analysis/gtest.cpp === --- cfe/trunk/test/Analysis/gtest.cpp +++ cfe/trunk/test/Analysis/gtest.cpp @@ -151,3 +151,17 @@ ASSERT_TRUE(false); clang_analyzer_warnIfReached(); // no-warning } + +void testAssertSymbolicPtr(const bool *b) { + ASSERT_TRUE(*b); // no-crash + + // FIXME: Our solver doesn't handle this well yet. + clang_analyzer_eval(*b); // expected-warning{{UNKNOWN}} +} + +void testAssertSymbolicRef(const bool &b) { + ASSERT_TRUE(b); // no-crash + + // FIXME: Our solver doesn't handle this well yet. + clang_analyzer_eval(b); // expected-warning{{UNKNOWN}} +} Index: cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp === --- cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp +++ cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -1393,16 +1393,19 @@ return UnknownVal(); } - if (isa(MR) || - isa(MR) || - isa(MR)) { + if (!isa(MR)) { if (T.isNull()) { if (const TypedRegion *TR = dyn_cast(MR)) -T = TR->getLocationType(); - else { -const SymbolicRegion *SR = cast(MR); -T = SR->getSymbol()->getType(); - } +T = TR->getLocationType()->getPointeeType(); + else if (const SymbolicRegion *SR = dyn_cast(MR)) +T = SR->getSymbol()->getType()->getPointeeType(); + else if (isa(MR)) +T = Ctx.VoidTy; +} +assert(!T.isNull() && "Unable to auto-detect binding type!"); +if (T->isVoidType()) { + // When trying to dereference a void pointer, read the first byte. + T = Ctx.CharTy; } MR = GetElementZeroRegion(cast(MR), T
[PATCH] D35216: [analyzer] Escape symbols when creating std::initializer_list.
This revision was automatically updated to reflect the committed changes. Closed by commit rL314975: [analyzer] Fix leak false positives on stuff put in C++/ObjC initializer lists. (authored by dergachev). Changed prior to commit: https://reviews.llvm.org/D35216?vs=117699&id=117785#toc Repository: rL LLVM https://reviews.llvm.org/D35216 Files: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp cfe/trunk/test/Analysis/initializer.cpp cfe/trunk/test/Analysis/objc-boxing.m cfe/trunk/test/Analysis/objc-for.m Index: cfe/trunk/test/Analysis/initializer.cpp === --- cfe/trunk/test/Analysis/initializer.cpp +++ cfe/trunk/test/Analysis/initializer.cpp @@ -1,7 +1,9 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=constructors -std=c++11 -verify %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,cplusplus.NewDeleteLeaks,debug.ExprInspection -analyzer-config c++-inlining=constructors -std=c++11 -verify %s void clang_analyzer_eval(bool); +#include "Inputs/system-header-simulator-cxx.h" + class A { int x; public: @@ -204,3 +206,17 @@ const char(&f)[2]; }; } + +namespace CXX_initializer_lists { +struct C { + C(std::initializer_list list); +}; +void foo() { + C empty{}; // no-crash + + // Do not warn that 'x' leaks. It might have been deleted by + // the destructor of 'c'. + int *x = new int; + C c{x}; // no-warning +} +} Index: cfe/trunk/test/Analysis/objc-for.m === --- cfe/trunk/test/Analysis/objc-for.m +++ cfe/trunk/test/Analysis/objc-for.m @@ -1,6 +1,7 @@ // RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.Loops,debug.ExprInspection -verify %s void clang_analyzer_eval(int); +void clang_analyzer_warnIfReached(); #define nil ((id)0) @@ -20,11 +21,13 @@ @interface NSArray : NSObject - (NSUInteger)count; - (NSEnumerator *)objectEnumerator; ++ (NSArray *)arrayWithObjects:(const id [])objects count:(NSUInteger)count; @end @interface NSDictionary : NSObject - (NSUInteger)count; - (id)objectForKey:(id)key; ++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id /* */ [])keys count:(NSUInteger)count; @end @interface NSDictionary (SomeCategory) @@ -324,3 +327,19 @@ for (id key in array) clang_analyzer_eval(0); // expected-warning{{FALSE}} } + +NSArray *globalArray; +NSDictionary *globalDictionary; +void boxedArrayEscape(NSMutableArray *array) { + if ([array count]) +return; + globalArray = @[array]; + for (id key in array) +clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} + + if ([array count]) +return; + globalDictionary = @{ @"array" : array }; + for (id key in array) +clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} +} Index: cfe/trunk/test/Analysis/objc-boxing.m === --- cfe/trunk/test/Analysis/objc-boxing.m +++ cfe/trunk/test/Analysis/objc-boxing.m @@ -5,6 +5,16 @@ typedef signed char BOOL; typedef long NSInteger; typedef unsigned long NSUInteger; + +@protocol NSObject +@end +@interface NSObject {} +@end +@protocol NSCopying +@end +@protocol NSCoding +@end + @interface NSString @end @interface NSString (NSStringExtensionMethods) + (id)stringWithUTF8String:(const char *)nullTerminatedCString; @@ -28,7 +38,15 @@ + (NSNumber *)numberWithUnsignedInteger:(NSUInteger)value ; @end +@interface NSValue : NSObject +- (void)getValue:(void *)value; ++ (NSValue *)valueWithBytes:(const void *)value + objCType:(const char *)type; +@end +typedef typeof(sizeof(int)) size_t; +extern void *malloc(size_t); +extern void free(void *); extern char *strdup(const char *str); id constant_string() { @@ -39,6 +57,23 @@ return @(strdup("boxed dynamic string")); // expected-warning{{Potential memory leak}} } +typedef struct __attribute__((objc_boxable)) { + const char *str; +} BoxableStruct; + +id leak_within_boxed_struct() { + BoxableStruct bs; + bs.str = strdup("dynamic string"); // The duped string shall be owned by val. + NSValue *val = @(bs); // no-warning + return val; +} + +id leak_of_boxed_struct() { + BoxableStruct *bs = malloc(sizeof(BoxableStruct)); // The pointer stored in bs isn't owned by val. + NSValue *val = @(*bs); // expected-warning{{Potential leak of memory pointed to by 'bs'}} + return val; +} + id const_char_pointer(int *x) { if (x) return @(3); Index: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp === --- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -827,6 +827,21 @@ } } +namespace { +class CollectReachableSymbolsCallback final : public SymbolVisitor { + InvalidatedSymbols Symbols; + +public: + explicit CollectReachableSymbolsCa
[PATCH] D38583: [clangd] Added async API to run code completion.
This revision was automatically updated to reflect the committed changes. Closed by commit rL314989: [clangd] Added async API to run code completion. (authored by ibiryukov). Repository: rL LLVM https://reviews.llvm.org/D38583 Files: clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp clang-tools-extra/trunk/clangd/ClangdServer.cpp clang-tools-extra/trunk/clangd/ClangdServer.h clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp Index: clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp === --- clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp +++ clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp @@ -473,13 +473,13 @@ // thread. FS.Tag = "123"; Server.addDocument(FooCpp, SourceContents); - EXPECT_EQ(Server.codeComplete(FooCpp, Position{0, 0}).Tag, FS.Tag); + EXPECT_EQ(Server.codeComplete(FooCpp, Position{0, 0}).get().Tag, FS.Tag); EXPECT_EQ(DiagConsumer.lastVFSTag(), FS.Tag); FS.Tag = "321"; Server.addDocument(FooCpp, SourceContents); EXPECT_EQ(DiagConsumer.lastVFSTag(), FS.Tag); - EXPECT_EQ(Server.codeComplete(FooCpp, Position{0, 0}).Tag, FS.Tag); + EXPECT_EQ(Server.codeComplete(FooCpp, Position{0, 0}).get().Tag, FS.Tag); } // Only enable this test on Unix @@ -631,7 +631,7 @@ { auto CodeCompletionResults1 = -Server.codeComplete(FooCpp, CompletePos, None).Value; +Server.codeComplete(FooCpp, CompletePos, None).get().Value; EXPECT_TRUE(ContainsItem(CodeCompletionResults1, "aba")); EXPECT_FALSE(ContainsItem(CodeCompletionResults1, "cbc")); } @@ -641,14 +641,15 @@ Server .codeComplete(FooCpp, CompletePos, StringRef(OverridenSourceContents)) +.get() .Value; EXPECT_TRUE(ContainsItem(CodeCompletionResultsOverriden, "cbc")); EXPECT_FALSE(ContainsItem(CodeCompletionResultsOverriden, "aba")); } { auto CodeCompletionResults2 = -Server.codeComplete(FooCpp, CompletePos, None).Value; +Server.codeComplete(FooCpp, CompletePos, None).get().Value; EXPECT_TRUE(ContainsItem(CodeCompletionResults2, "aba")); EXPECT_FALSE(ContainsItem(CodeCompletionResults2, "cbc")); } @@ -840,7 +841,13 @@ AddDocument(FileIndex); Position Pos{LineDist(RandGen), ColumnDist(RandGen)}; - Server.codeComplete(FilePaths[FileIndex], Pos); + // FIXME(ibiryukov): Also test async completion requests. + // Simply putting CodeCompletion into async requests now would make + // tests slow, since there's no way to cancel previous completion + // requests as opposed to AddDocument/RemoveDocument, which are implicitly + // cancelled by any subsequent AddDocument/RemoveDocument request to the + // same file. + Server.codeComplete(FilePaths[FileIndex], Pos).wait(); }; auto FindDefinitionsRequest = [&]() { Index: clang-tools-extra/trunk/clangd/ClangdServer.h === --- clang-tools-extra/trunk/clangd/ClangdServer.h +++ clang-tools-extra/trunk/clangd/ClangdServer.h @@ -231,19 +231,25 @@ /// and AST and rebuild them from scratch. std::future forceReparse(PathRef File); - /// Run code completion for \p File at \p Pos. If \p OverridenContents is not - /// None, they will used only for code completion, i.e. no diagnostics update - /// will be scheduled and a draft for \p File will not be updated. - /// If \p OverridenContents is None, contents of the current draft for \p File - /// will be used. - /// If \p UsedFS is non-null, it will be overwritten by vfs::FileSystem used - /// for completion. - /// This method should only be called for currently tracked - /// files. - Tagged> + /// Run code completion for \p File at \p Pos. + /// + /// Request is processed asynchronously. You can use the returned future to + /// wait for the results of the async request. + /// + /// If \p OverridenContents is not None, they will used only for code + /// completion, i.e. no diagnostics update will be scheduled and a draft for + /// \p File will not be updated. If \p OverridenContents is None, contents of + /// the current draft for \p File will be used. If \p UsedFS is non-null, it + /// will be overwritten by vfs::FileSystem used for completion. + /// + /// This method should only be called for currently tracked files. However, it + /// is safe to call removeDocument for \p File after this method returns, even + /// while returned future is not yet ready. + std::future>> codeComplete(PathRef File, Position Pos, llvm::Optional OverridenContents = llvm::None, IntrusiveRefCntPtr *UsedFS = nullptr); + /// Get definition of symbol at a specified \p Line and \p Column in \p File. Tagged> findDefinitions(PathRef File, Position Pos); Index: clang-tools-extra/trunk/clangd/ClangdServer.cpp ===
[PATCH] D38048: [clangd] Add textDocument/signatureHelp
This revision was automatically updated to reflect the committed changes. Closed by commit rL315055: [clangd] Add textDocument/signatureHelp (authored by ibiryukov). Changed prior to commit: https://reviews.llvm.org/D38048?vs=117580&id=117983#toc Repository: rL LLVM https://reviews.llvm.org/D38048 Files: clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp clang-tools-extra/trunk/clangd/ClangdLSPServer.h clang-tools-extra/trunk/clangd/ClangdServer.cpp clang-tools-extra/trunk/clangd/ClangdServer.h clang-tools-extra/trunk/clangd/ClangdUnit.cpp clang-tools-extra/trunk/clangd/ClangdUnit.h clang-tools-extra/trunk/clangd/Protocol.cpp clang-tools-extra/trunk/clangd/Protocol.h clang-tools-extra/trunk/clangd/ProtocolHandlers.cpp clang-tools-extra/trunk/clangd/ProtocolHandlers.h clang-tools-extra/trunk/test/clangd/formatting.test clang-tools-extra/trunk/test/clangd/initialize-params-invalid.test clang-tools-extra/trunk/test/clangd/initialize-params.test clang-tools-extra/trunk/test/clangd/signature-help.test Index: clang-tools-extra/trunk/test/clangd/signature-help.test === --- clang-tools-extra/trunk/test/clangd/signature-help.test +++ clang-tools-extra/trunk/test/clangd/signature-help.test @@ -0,0 +1,42 @@ +# RUN: clangd -run-synchronously < %s | FileCheck %s +# It is absolutely vital that this file has CRLF line endings. + +# Start a session. +Content-Length: 125 + +{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}} + +# Modify the document. +Content-Length: 333 + +{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"void foo(int x, int y);\nvoid foo(int x, float y);\nvoid foo(float x, int y);\nvoid foo(float x, float y);\nvoid bar(int x, int y = 0);\nvoid bar(float x = 0, int y = 42);\nint main() { foo("}}} + +# Ask for signature help. +Content-Length: 151 + +{"jsonrpc":"2.0","id":1,"method":"textDocument/signatureHelp","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":8,"character":9}}} +# CHECK: {"jsonrpc":"2.0","id":1,"result":{"activeSignature":0,"activeParameter":0,"signatures":[ +# CHECK-DAG: {"label":"foo(float x, float y) -> void","parameters":[{"label":"float x"},{"label":"float y"}]} +# CHECK-DAG: {"label":"foo(float x, int y) -> void","parameters":[{"label":"float x"},{"label":"int y"}]} +# CHECK-DAG: {"label":"foo(int x, float y) -> void","parameters":[{"label":"int x"},{"label":"float y"}]} +# CHECK-DAG: {"label":"foo(int x, int y) -> void","parameters":[{"label":"int x"},{"label":"int y"}]} +# CHECK: ]} + +# Modify the document +Content-Length: 333 + +{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":2,"text":"void foo(int x, int y);\nvoid foo(int x, float y);\nvoid foo(float x, int y);\nvoid foo(float x, float y);\nvoid bar(int x, int y = 0);\nvoid bar(float x = 0, int y = 42);\nint main() { bar("}}} + +# Ask for signature help (this checks default argument handling). +Content-Length: 151 + +{"jsonrpc":"2.0","id":2,"method":"textDocument/signatureHelp","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":8,"character":9}}} +# CHECK: {"jsonrpc":"2.0","id":2,"result":{"activeSignature":0,"activeParameter":0,"signatures":[ +# CHECK-DAG: {"label":"bar(int x, int y = 0) -> void","parameters":[{"label":"int x"},{"label":"int y = 0"}]} +# CHECK-DAG: {"label":"bar(float x = 0, int y = 42) -> void","parameters":[{"label":"float x = 0"},{"label":"int y = 42"}]} +# CHECK: ]} + +# Shutdown. +Content-Length: 49 + +{"jsonrpc":"2.0","id":10,"method":"shutdown"} Index: clang-tools-extra/trunk/test/clangd/initialize-params.test === --- clang-tools-extra/trunk/test/clangd/initialize-params.test +++ clang-tools-extra/trunk/test/clangd/initialize-params.test @@ -5,14 +5,15 @@ Content-Length: 143 {"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootUri":"file:///path/to/workspace","capabilities":{},"trace":"off"}} -# CHECK: Content-Length: 466 +# CHECK: Content-Length: 535 # CHECK: {"jsonrpc":"2.0","id":0,"result":{"capabilities":{ # CHECK: "textDocumentSync": 1, # CHECK: "documentFormattingProvider": true, # CHECK: "documentRangeFormattingProvider": true, # CHECK: "documentOnTypeFormattingProvider": {"firstTriggerCharacter":"}","moreTriggerCharacter":[]}, # CHECK: "codeActionProvider": true, # CHECK: "completionProvider": {"resolveProvider": false, "triggerCharacters": [".",">",":"]}, +# CHECK: "signatureHelpProvider": {"triggerCharacters": ["(",","]}, # CHECK: "definitionProvider": true # CHECK: }}} # Index: clang-tools-extra/trunk/test/clangd/formatting.test ==
[PATCH] D38627: [clangd] Added move-only function helpers.
This revision was automatically updated to reflect the committed changes. Closed by commit rL315210: [clangd] Added move-only function helpers. (authored by ibiryukov). Repository: rL LLVM https://reviews.llvm.org/D38627 Files: clang-tools-extra/trunk/clangd/ClangdServer.cpp clang-tools-extra/trunk/clangd/ClangdServer.h clang-tools-extra/trunk/clangd/Function.h Index: clang-tools-extra/trunk/clangd/Function.h === --- clang-tools-extra/trunk/clangd/Function.h +++ clang-tools-extra/trunk/clangd/Function.h @@ -0,0 +1,136 @@ +//===--- Function.h - Utility callable wrappers -*- C++-*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// +// +// This file provides an analogue to std::function that supports move semantics. +// +//===--===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_FUNCTION_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_FUNCTION_H + +#include +#include +#include + +namespace clang { +namespace clangd { + +/// A move-only type-erasing function wrapper. Similar to `std::function`, but +/// allows to store move-only callables. +template class UniqueFunction; + +template class UniqueFunction { +public: + UniqueFunction() = default; + UniqueFunction(std::nullptr_t) : UniqueFunction(){}; + + UniqueFunction(UniqueFunction const &) = delete; + UniqueFunction &operator=(UniqueFunction const &) = delete; + + UniqueFunction(UniqueFunction &&) noexcept = default; + UniqueFunction &operator=(UniqueFunction &&) noexcept = default; + + template + UniqueFunction(Callable &&Func) + : CallablePtr(llvm::make_unique< +FunctionCallImpl::type>>( +std::forward(Func))) {} + + operator bool() { return CallablePtr; } + + Ret operator()(Args... As) { +assert(CallablePtr); +CallablePtr->Call(std::forward(As)...); + } + +private: + class FunctionCallBase { + public: +virtual ~FunctionCallBase() = default; +virtual Ret Call(Args... As) = 0; + }; + + template + class FunctionCallImpl final : public FunctionCallBase { +static_assert( +std::is_same::type>::value, +"FunctionCallImpl must be instanstiated with std::decay'ed types"); + + public: +FunctionCallImpl(Callable Func) : Func(std::move(Func)) {} + +Ret Call(Args... As) override { return Func(std::forward(As)...); } + + private: +Callable Func; + }; + + std::unique_ptr CallablePtr; +}; + +/// Stores a callable object (Func) and arguments (Args) and allows to call the +/// callable with provided arguments later using `operator ()`. The arguments +/// are std::forward'ed into the callable in the body of `operator()`. Therefore +/// `operator()` can only be called once, as some of the arguments could be +/// std::move'ed into the callable on first call. +template struct ForwardBinder { + using Tuple = std::tuple::type, + typename std::decay::type...>; + Tuple FuncWithArguments; +#ifndef NDEBUG + bool WasCalled = false; +#endif + +public: + ForwardBinder(Tuple FuncWithArguments) + : FuncWithArguments(std::move(FuncWithArguments)) {} + +private: + template + auto CallImpl(llvm::integer_sequence Seq, +RestArgs &&... Rest) + -> decltype(std::get<0>(this->FuncWithArguments)( + std::forward(std::get(this->FuncWithArguments))..., + std::forward(Rest)...)) { +return std::get<0>(this->FuncWithArguments)( +std::forward(std::get(this->FuncWithArguments))..., +std::forward(Rest)...); + } + +public: + template + auto operator()(RestArgs &&... Rest) + -> decltype(CallImpl(llvm::index_sequence_for(), + std::forward(Rest)...)) { + +#ifndef NDEBUG +assert(!WasCalled && "Can only call result of BindWithForward once."); +WasCalled = true; +#endif +return CallImpl(llvm::index_sequence_for(), +std::forward(Rest)...); + } +}; + +/// Creates an object that stores a callable (\p F) and first arguments to the +/// callable (\p As) and allows to call \p F with \Args at a later point. +/// Similar to std::bind, but also works with move-only \p F and \p As. +/// +/// The returned object must be called no more than once, as \p As are +/// std::forwarded'ed (therefore can be moved) into \p F during the call. +template +ForwardBinder BindWithForward(Func F, Args &&... As) { + return ForwardBinder( + std::make_tuple(std::forward(F), std::forward(As)...)); +} + +} // namespace clangd +} // namespace clang + +#endif Index: clang-tools-extra/trunk/clangd/ClangdServer.h === --- clang-tools-extra/trunk/c
[PATCH] D38617: Set PreprocessorOpts.GeneratePreamble=true in PrecompiledPreamble.
This revision was automatically updated to reflect the committed changes. Closed by commit rL315212: Set PreprocessorOpts.GeneratePreamble=true in PrecompiledPreamble. (authored by ibiryukov). Repository: rL LLVM https://reviews.llvm.org/D38617 Files: cfe/trunk/lib/Frontend/ASTUnit.cpp cfe/trunk/lib/Frontend/PrecompiledPreamble.cpp Index: cfe/trunk/lib/Frontend/ASTUnit.cpp === --- cfe/trunk/lib/Frontend/ASTUnit.cpp +++ cfe/trunk/lib/Frontend/ASTUnit.cpp @@ -1698,7 +1698,6 @@ PreprocessorOptions &PPOpts = CI->getPreprocessorOpts(); PPOpts.RemappedFilesKeepOriginalName = RemappedFilesKeepOriginalName; PPOpts.AllowPCHWithCompilerErrors = AllowPCHWithCompilerErrors; - PPOpts.GeneratePreamble = PrecompilePreambleAfterNParses != 0; PPOpts.SingleFileParseMode = SingleFileParse; // Override the resources path. Index: cfe/trunk/lib/Frontend/PrecompiledPreamble.cpp === --- cfe/trunk/lib/Frontend/PrecompiledPreamble.cpp +++ cfe/trunk/lib/Frontend/PrecompiledPreamble.cpp @@ -234,6 +234,8 @@ FrontendOpts.OutputFile = PreamblePCHFile->getFilePath(); PreprocessorOpts.PrecompiledPreambleBytes.first = 0; PreprocessorOpts.PrecompiledPreambleBytes.second = false; + // Inform preprocessor to record conditional stack when building the preamble. + PreprocessorOpts.GeneratePreamble = true; // Create the compiler instance to use for building the precompiled preamble. std::unique_ptr Clang( Index: cfe/trunk/lib/Frontend/ASTUnit.cpp === --- cfe/trunk/lib/Frontend/ASTUnit.cpp +++ cfe/trunk/lib/Frontend/ASTUnit.cpp @@ -1698,7 +1698,6 @@ PreprocessorOptions &PPOpts = CI->getPreprocessorOpts(); PPOpts.RemappedFilesKeepOriginalName = RemappedFilesKeepOriginalName; PPOpts.AllowPCHWithCompilerErrors = AllowPCHWithCompilerErrors; - PPOpts.GeneratePreamble = PrecompilePreambleAfterNParses != 0; PPOpts.SingleFileParseMode = SingleFileParse; // Override the resources path. Index: cfe/trunk/lib/Frontend/PrecompiledPreamble.cpp === --- cfe/trunk/lib/Frontend/PrecompiledPreamble.cpp +++ cfe/trunk/lib/Frontend/PrecompiledPreamble.cpp @@ -234,6 +234,8 @@ FrontendOpts.OutputFile = PreamblePCHFile->getFilePath(); PreprocessorOpts.PrecompiledPreambleBytes.first = 0; PreprocessorOpts.PrecompiledPreambleBytes.second = false; + // Inform preprocessor to record conditional stack when building the preamble. + PreprocessorOpts.GeneratePreamble = true; // Create the compiler instance to use for building the precompiled preamble. std::unique_ptr Clang( ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D37970: [clangd] Added a command-line arg to mirror clangd input into a file.
This revision was automatically updated to reflect the committed changes. Closed by commit rL315214: [clangd] Added a command-line arg to mirror clangd input into a file. (authored by ibiryukov). Changed prior to commit: https://reviews.llvm.org/D37970?vs=115628&id=118223#toc Repository: rL LLVM https://reviews.llvm.org/D37970 Files: clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp clang-tools-extra/trunk/clangd/JSONRPCDispatcher.h clang-tools-extra/trunk/clangd/tool/ClangdMain.cpp clang-tools-extra/trunk/test/clangd/input-mirror.test Index: clang-tools-extra/trunk/test/clangd/input-mirror.test === --- clang-tools-extra/trunk/test/clangd/input-mirror.test +++ clang-tools-extra/trunk/test/clangd/input-mirror.test @@ -0,0 +1,154 @@ +# RUN: clangd -run-synchronously -input-mirror-file %t < %s +# Note that we have to use '-Z' as -input-mirror-file does not have a newline at the end of file. +# RUN: diff -Z %t %s +# It is absolutely vital that this file has CRLF line endings. +# +Content-Length: 125 + +{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}} + +Content-Length: 172 + +{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///main.cpp","languageId":"cpp","version":1,"text":"int main() {\nint a;\na;\n}\n"}}} + +Content-Length: 148 + +{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":2,"character":0}}} +# Go to local variable + +Content-Length: 148 + +{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":2,"character":1}}} +# Go to local variable, end of token + +Content-Length: 214 + +{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"file:///main.cpp","version":2},"contentChanges":[{"text":"struct Foo {\nint x;\n};\nint main() {\n Foo bar = { x : 1 };\n}\n"}]}} + +Content-Length: 149 + +{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":4,"character":14}}} +# Go to field, GNU old-style field designator + +Content-Length: 215 + +{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"file:///main.cpp","version":3},"contentChanges":[{"text":"struct Foo {\nint x;\n};\nint main() {\n Foo baz = { .x = 2 };\n}\n"}]}} + +Content-Length: 149 + +{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":4,"character":15}}} +# Go to field, field designator + +Content-Length: 187 + +{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"file:///main.cpp","version":4},"contentChanges":[{"text":"int main() {\n main();\n return 0;\n}"}]}} + +Content-Length: 148 + +{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":1,"character":3}}} +# Go to function declaration, function call + +Content-Length: 208 + +{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"file:///main.cpp","version":5},"contentChanges":[{"text":"struct Foo {\n};\nint main() {\n Foo bar;\n return 0;\n}\n"}]}} + +Content-Length: 148 + +{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":3,"character":3}}} +# Go to struct declaration, new struct instance + +Content-Length: 231 + +{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"file:///main.cpp","version":5},"contentChanges":[{"text":"namespace n1 {\nstruct Foo {\n};\n}\nint main() {\n n1::Foo bar;\n return 0;\n}\n"}]}} + +Content-Length: 148 + +{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":5,"character":4}}} +# Go to struct declaration, new struct instance, qualified name + +Content-Length: 215 + +{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"file:///main.cpp","version":6},"contentChanges":[{"text":"struct Foo {\n int x;\n};\nint main() {\n Foo bar;\n bar.x;\n}\n"}]}} + +Content-Length: 148 + +{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":5,"character":7}}} +# Go to field declaration, field reference + +Content-Length: 220 + +{"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"file:///main.cpp","version":7},"contentChanges":[{"text":"struct Foo {\n void x();\n};\nint main() {\n Foo bar;\n bar.x();\n}\n"}]}} + +Content-Length: 148 + +{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{"textDocument":{"uri":"file:///main.cpp"},"
[PATCH] D38643: PR13575: Fix USR mangling for fixed-size arrays.
This revision was automatically updated to reflect the committed changes. Closed by commit rL315236: PR13575: Fix USR mangling for fixed-size arrays (authored by jkorous). Changed prior to commit: https://reviews.llvm.org/D38643?vs=118247&id=118257#toc Repository: rL LLVM https://reviews.llvm.org/D38643 Files: cfe/trunk/lib/Index/USRGeneration.cpp cfe/trunk/test/Index/USR/array-type.cpp Index: cfe/trunk/test/Index/USR/array-type.cpp === --- cfe/trunk/test/Index/USR/array-type.cpp +++ cfe/trunk/test/Index/USR/array-type.cpp @@ -0,0 +1,11 @@ +// RUN: c-index-test core -print-source-symbols -- %s | FileCheck %s + +// Function template specializations differing in array type parameter should have unique USRs. + +template void foo(buffer); +// CHECK: {{[0-9]+}}:17 | function(Gen,TS)/C++ | foo | c:@F@foo<#{n16C>#*C# | __Z3fooIA16_cEvT_ | Decl,RelSpecialization | rel: 1 +template<> void foo(char[16]); +// CHECK: {{[0-9]+}}:17 | function(Gen,TS)/C++ | foo | c:@F@foo<#{n32C>#*C# | __Z3fooIA32_cEvT_ | Decl,RelSpecialization | rel: 1 +template<> void foo(char[32]); +// CHECK: {{[0-9]+}}:17 | function(Gen,TS)/C++ | foo | c:@F@foo<#{n64C>#*C# | __Z3fooIA64_cEvT_ | Decl,RelSpecialization | rel: 1 +template<> void foo(char[64]); Index: cfe/trunk/lib/Index/USRGeneration.cpp === --- cfe/trunk/lib/Index/USRGeneration.cpp +++ cfe/trunk/lib/Index/USRGeneration.cpp @@ -816,6 +816,25 @@ T = VT->getElementType(); continue; } +if (const auto *const AT = dyn_cast(T)) { + Out << '{'; + switch (AT->getSizeModifier()) { + case ArrayType::Static: +Out << 's'; +break; + case ArrayType::Star: +Out << '*'; +break; + case ArrayType::Normal: +Out << 'n'; +break; + } + if (const auto *const CAT = dyn_cast(T)) +Out << CAT->getSize(); + + T = AT->getElementType(); + continue; +} // Unhandled type. Out << ' '; Index: cfe/trunk/test/Index/USR/array-type.cpp === --- cfe/trunk/test/Index/USR/array-type.cpp +++ cfe/trunk/test/Index/USR/array-type.cpp @@ -0,0 +1,11 @@ +// RUN: c-index-test core -print-source-symbols -- %s | FileCheck %s + +// Function template specializations differing in array type parameter should have unique USRs. + +template void foo(buffer); +// CHECK: {{[0-9]+}}:17 | function(Gen,TS)/C++ | foo | c:@F@foo<#{n16C>#*C# | __Z3fooIA16_cEvT_ | Decl,RelSpecialization | rel: 1 +template<> void foo(char[16]); +// CHECK: {{[0-9]+}}:17 | function(Gen,TS)/C++ | foo | c:@F@foo<#{n32C>#*C# | __Z3fooIA32_cEvT_ | Decl,RelSpecialization | rel: 1 +template<> void foo(char[32]); +// CHECK: {{[0-9]+}}:17 | function(Gen,TS)/C++ | foo | c:@F@foo<#{n64C>#*C# | __Z3fooIA64_cEvT_ | Decl,RelSpecialization | rel: 1 +template<> void foo(char[64]); Index: cfe/trunk/lib/Index/USRGeneration.cpp === --- cfe/trunk/lib/Index/USRGeneration.cpp +++ cfe/trunk/lib/Index/USRGeneration.cpp @@ -816,6 +816,25 @@ T = VT->getElementType(); continue; } +if (const auto *const AT = dyn_cast(T)) { + Out << '{'; + switch (AT->getSizeModifier()) { + case ArrayType::Static: +Out << 's'; +break; + case ArrayType::Star: +Out << '*'; +break; + case ArrayType::Normal: +Out << 'n'; +break; + } + if (const auto *const CAT = dyn_cast(T)) +Out << CAT->getSize(); + + T = AT->getElementType(); + continue; +} // Unhandled type. Out << ' '; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38711: typos in documentation?
This revision was automatically updated to reflect the committed changes. Closed by commit rL315252: Fix typos in documentation (authored by jkorous). Changed prior to commit: https://reviews.llvm.org/D38711?vs=118295&id=118296#toc Repository: rL LLVM https://reviews.llvm.org/D38711 Files: cfe/trunk/docs/InternalsManual.rst Index: cfe/trunk/docs/InternalsManual.rst === --- cfe/trunk/docs/InternalsManual.rst +++ cfe/trunk/docs/InternalsManual.rst @@ -1540,7 +1540,7 @@ After trying several different approaches, we've finally converged on a design (Note, at the time of this writing, not all of this has been implemented, consider this a design goal!). Our basic approach is to define a single -recursive method evaluation method (``Expr::Evaluate``), which is implemented +recursive evaluation method (``Expr::Evaluate``), which is implemented in ``AST/ExprConstant.cpp``. Given an expression with "scalar" type (integer, fp, complex, or pointer) this method returns the following information: @@ -2037,7 +2037,7 @@ * ``CodeGenFunction`` contains functions ``ConvertType`` and ``ConvertTypeForMem`` that convert Clang's types (``clang::Type*`` or ``clang::QualType``) to LLVM types. Use the former for values, and the - later for memory locations: test with the C++ "``bool``" type to check + latter for memory locations: test with the C++ "``bool``" type to check this. If you find that you are having to use LLVM bitcasts to make the subexpressions of your expression have the type that your expression expects, STOP! Go fix semantic analysis and the AST so that you don't Index: cfe/trunk/docs/InternalsManual.rst === --- cfe/trunk/docs/InternalsManual.rst +++ cfe/trunk/docs/InternalsManual.rst @@ -1540,7 +1540,7 @@ After trying several different approaches, we've finally converged on a design (Note, at the time of this writing, not all of this has been implemented, consider this a design goal!). Our basic approach is to define a single -recursive method evaluation method (``Expr::Evaluate``), which is implemented +recursive evaluation method (``Expr::Evaluate``), which is implemented in ``AST/ExprConstant.cpp``. Given an expression with "scalar" type (integer, fp, complex, or pointer) this method returns the following information: @@ -2037,7 +2037,7 @@ * ``CodeGenFunction`` contains functions ``ConvertType`` and ``ConvertTypeForMem`` that convert Clang's types (``clang::Type*`` or ``clang::QualType``) to LLVM types. Use the former for values, and the - later for memory locations: test with the C++ "``bool``" type to check + latter for memory locations: test with the C++ "``bool``" type to check this. If you find that you are having to use LLVM bitcasts to make the subexpressions of your expression have the type that your expression expects, STOP! Go fix semantic analysis and the AST so that you don't ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D38707: PR13575: Fix USR mangling for functions taking function pointers as arguments.
This revision was automatically updated to reflect the committed changes. Closed by commit rL315255: R13575: Fix USR mangling for function pointer types (authored by jkorous). Changed prior to commit: https://reviews.llvm.org/D38707?vs=118287&id=118300#toc Repository: rL LLVM https://reviews.llvm.org/D38707 Files: cfe/trunk/lib/Index/USRGeneration.cpp cfe/trunk/test/Index/USR/func-type.cpp Index: cfe/trunk/lib/Index/USRGeneration.cpp === --- cfe/trunk/lib/Index/USRGeneration.cpp +++ cfe/trunk/lib/Index/USRGeneration.cpp @@ -754,8 +754,12 @@ if (const FunctionProtoType *FT = T->getAs()) { Out << 'F'; VisitType(FT->getReturnType()); - for (const auto &I : FT->param_types()) + Out << '('; + for (const auto &I : FT->param_types()) { +Out << '#'; VisitType(I); + } + Out << ')'; if (FT->isVariadic()) Out << '.'; return; Index: cfe/trunk/test/Index/USR/func-type.cpp === --- cfe/trunk/test/Index/USR/func-type.cpp +++ cfe/trunk/test/Index/USR/func-type.cpp @@ -0,0 +1,18 @@ +// RUN: c-index-test core -print-source-symbols -- %s | FileCheck %s + +// Functions taking function pointer parameters with different signatures should result in unique USRs. + +typedef void (*_VoidToVoidPtr_)(); +typedef void (*_IntToVoidPtr_)( int ); +typedef _VoidToVoidPtr_ (*IntTo_VoidToVoidPtr_Ptr)( int ); +typedef _IntToVoidPtr_ (*VoidTo_IntToVoidPtr_Ptr)(); + +void Func( IntTo_VoidToVoidPtr_Ptr ); +// CHECK: {{[0-9]+}}:6 | function/C | Func | c:@F@Func#*F*Fv()(#I)# | +void Func( VoidTo_IntToVoidPtr_Ptr ); +// CHECK: {{[0-9]+}}:6 | function/C | Func | c:@F@Func#*F*Fv(#I)()# | + +void Func( void (* (*)(int, int))(int, int) ); +// CHECK: {{[0-9]+}}:6 | function/C | Func | c:@F@Func#*F*Fv(#I#I)(#I#I)# | +void Func( void (* (*)(int, int, int))(int) ); +// CHECK: {{[0-9]+}}:6 | function/C | Func | c:@F@Func#*F*Fv(#I)(#I#I#I)# | Index: cfe/trunk/lib/Index/USRGeneration.cpp === --- cfe/trunk/lib/Index/USRGeneration.cpp +++ cfe/trunk/lib/Index/USRGeneration.cpp @@ -754,8 +754,12 @@ if (const FunctionProtoType *FT = T->getAs()) { Out << 'F'; VisitType(FT->getReturnType()); - for (const auto &I : FT->param_types()) + Out << '('; + for (const auto &I : FT->param_types()) { +Out << '#'; VisitType(I); + } + Out << ')'; if (FT->isVariadic()) Out << '.'; return; Index: cfe/trunk/test/Index/USR/func-type.cpp === --- cfe/trunk/test/Index/USR/func-type.cpp +++ cfe/trunk/test/Index/USR/func-type.cpp @@ -0,0 +1,18 @@ +// RUN: c-index-test core -print-source-symbols -- %s | FileCheck %s + +// Functions taking function pointer parameters with different signatures should result in unique USRs. + +typedef void (*_VoidToVoidPtr_)(); +typedef void (*_IntToVoidPtr_)( int ); +typedef _VoidToVoidPtr_ (*IntTo_VoidToVoidPtr_Ptr)( int ); +typedef _IntToVoidPtr_ (*VoidTo_IntToVoidPtr_Ptr)(); + +void Func( IntTo_VoidToVoidPtr_Ptr ); +// CHECK: {{[0-9]+}}:6 | function/C | Func | c:@F@Func#*F*Fv()(#I)# | +void Func( VoidTo_IntToVoidPtr_Ptr ); +// CHECK: {{[0-9]+}}:6 | function/C | Func | c:@F@Func#*F*Fv(#I)()# | + +void Func( void (* (*)(int, int))(int, int) ); +// CHECK: {{[0-9]+}}:6 | function/C | Func | c:@F@Func#*F*Fv(#I#I)(#I#I)# | +void Func( void (* (*)(int, int, int))(int) ); +// CHECK: {{[0-9]+}}:6 | function/C | Func | c:@F@Func#*F*Fv(#I)(#I#I#I)# | ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits