[PATCH] D53771: [clang-tidy] Avoid C arrays check
lebedev.ri updated this revision to Diff 171393. lebedev.ri marked 9 inline comments as done. lebedev.ri edited the summary of this revision. lebedev.ri added a comment. - Moved into `modernize` - Detect based on `TypeLoc`, which means we now catch *everything*, including `using`-declarations. Note the `unique_ptr` example. Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D53771 Files: clang-tidy/modernize/AvoidCArraysCheck.cpp clang-tidy/modernize/AvoidCArraysCheck.h clang-tidy/modernize/CMakeLists.txt clang-tidy/modernize/ModernizeTidyModule.cpp docs/ReleaseNotes.rst docs/clang-tidy/checks/list.rst docs/clang-tidy/checks/modernize-avoid-c-arrays.rst test/clang-tidy/modernize-avoid-c-arrays.cpp Index: test/clang-tidy/modernize-avoid-c-arrays.cpp === --- /dev/null +++ test/clang-tidy/modernize-avoid-c-arrays.cpp @@ -0,0 +1,59 @@ +// RUN: %check_clang_tidy %s modernize-avoid-c-arrays %t + +int a[] = {1, 2}; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: do not declare C-style arrays, use std::array<> instead + +int b[1]; +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: do not declare C-style arrays, use std::array<> instead + +void foo() { + int c[b[0]]; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead +} + +template +class array { + T d[Size]; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead + + int e[1]; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead +}; + +array d; +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not declare C-style arrays, use std::array<> instead + +using k = int[4]; +// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: do not declare C-style arrays, use std::array<> instead + +array dk; + +template +class unique_ptr { + T *d; + + int e[1]; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead +}; + +unique_ptr d2; +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: do not declare C-style arrays, use std::array<> instead + +using k2 = int[]; +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: do not declare C-style arrays, use std::array<> instead + +unique_ptr dk2; + +// Some header +extern "C" { + +int f[] = {1, 2}; + +int j[1]; + +inline void bar() { + { +int j[j[0]]; + } +} +} Index: docs/clang-tidy/checks/modernize-avoid-c-arrays.rst === --- /dev/null +++ docs/clang-tidy/checks/modernize-avoid-c-arrays.rst @@ -0,0 +1,53 @@ +.. title:: clang-tidy - modernize-avoid-c-arrays + +modernize-avoid-c-arrays +=== + +Finds C-style array declarations and recommend to use ``std::array<>``. +All types of C arrays are diagnosed. + +However, no fix-its are provided. Such transform would need to be able to +observe *all* the uses of said declaration in order to decide whether it is +safe to transform or not, and that is impossible in case of headers. + +.. code:: c++ + + int a[] = {1, 2}; // warning: do not declare C-style arrays, use std::array<> instead + + int b[1]; // warning: do not declare C-style arrays, use std::array<> instead + + void foo() { +int c[b[0]]; // warning: do not declare C-style arrays, use std::array<> instead + } + + template + class array { +T d[Size]; // warning: do not declare C-style arrays, use std::array<> instead + +int e[1]; // warning: do not declare C-style arrays, use std::array<> instead + }; + + array d; // warning: do not declare C-style arrays, use std::array<> instead + + using k = int[4]; // warning: do not declare C-style arrays, use std::array<> instead + + +However, the ``extern "C"`` code is ignored, since it is common to share +such headers between C code, and C++ code. + +.. code:: c++ + + // Some header + extern "C" { + + int f[] = {1, 2}; // not diagnosed + + int j[1]; // not diagnosed + + inline void bar() { +{ + int j[j[0]]; // not diagnosed +} + } + + } Index: docs/clang-tidy/checks/list.rst === --- docs/clang-tidy/checks/list.rst +++ docs/clang-tidy/checks/list.rst @@ -178,6 +178,7 @@ misc-unused-parameters misc-unused-using-decls modernize-avoid-bind + modernize-avoid-c-arrays modernize-concat-nested-namespaces modernize-deprecated-headers modernize-deprecated-ios-base-aliases Index: docs/ReleaseNotes.rst === --- docs/ReleaseNotes.rst +++ docs/ReleaseNotes.rst @@ -123,6 +123,11 @@ but also have logic (non-static member functions), and diagnoses all member variables that have any other scope other than ``private``. +- New :doc:`modernize-avoid-c-arrays + ` check. + + Finds C-style array declarations and recommend to use ``std::array<>``. + - New :doc:`modernize-concat-n
[PATCH] D53076: [analyzer] Enhance ConditionBRVisitor to write out more information
Charusso added inline comments. Comment at: test/Analysis/MisusedMovedObject.cpp:187 A a; -if (i == 1) { // expected-note {{Taking false branch}} expected-note {{Taking false branch}} +if (i == 1) { // expected-note {{Assuming 'i' is not equal to 1}} expected-note {{Taking false branch}} + // expected-note@-1 {{Assuming 'i' is not equal to 1}} expected-note@-1 {{Taking false branch}} NoQ wrote: > These assumptions were already made on the previous branches. There should be > no extra assumptions here. Agree but only if there is no extra constraint EventPiece between them. Comment at: test/Analysis/MisusedMovedObject.cpp:221 } -if (i > 5) { // expected-note {{Taking true branch}} +if (i > 5) { // expected-note {{Assuming 'i' is > 5}} expected-note {{Taking true branch}} a.foo(); // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}} NoQ wrote: > We have assumed that `i` is `>= 10` on the previous branch. It imples that > `i` is greater than `5`, so no additional assumption is being made here. Agree but only if there is no extra constraint EventPiece between them. Comment at: test/Analysis/NewDelete-path-notes.cpp:10 if (p) -// expected-note@-1 {{Taking true branch}} +// expected-note@-1 {{Assuming 'p' is non-null}} +// expected-note@-2 {{Taking true branch}} NoQ wrote: > Static Analyzer knows that the standard operator new never returns null. > Therefore no assumption is being made here. As I see SA knows nothing. Where to teach it? Comment at: test/Analysis/inline-plist.c:46 if (p == 0) { -// expected-note@-1 {{Taking true branch}} +// expected-note@-1 {{Assuming 'p' is equal to null}} +// expected-note@-2 {{Taking true branch}} NoQ wrote: > The condition `!!p` above being assumed to false ensures that `p` is equal to > `null` here. We are not assuming it again here. Agree but only if there is no extra constraint EventPiece between them. https://reviews.llvm.org/D53076 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D53076: [analyzer] Enhance ConditionBRVisitor to write out more information
Charusso added inline comments. Comment at: test/Analysis/Inputs/expected-plists/cxx-for-range.cpp.plist:837 + message + Variable 'fail' is true + Double negating is not in standard English, so this behaviour is documented here. Comment at: test/Analysis/Inputs/expected-plists/edges-new.mm.plist:9629 + Variable 'z' is equal to 0 + + @NoQ this is the only place (as I see) where SA works with flow-sensitive constraint-handling what you mentioned. Is it a good change? https://reviews.llvm.org/D53076 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D53771: [clang-tidy] Avoid C arrays check
Eugene.Zelenko added a comment. Will be good idea to add aliases at least for existing modules. Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D53771 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r345446 - Revert r345170 [along with its llvm counterpart r345169] as it makes Halide builds timeout.
Author: asbirlea Date: Fri Oct 26 21:51:09 2018 New Revision: 345446 URL: http://llvm.org/viewvc/llvm-project?rev=345446&view=rev Log: Revert r345170 [along with its llvm counterpart r345169] as it makes Halide builds timeout. Modified: cfe/trunk/lib/Driver/ToolChains/Hexagon.cpp cfe/trunk/test/Driver/hexagon-vectorize.c Modified: cfe/trunk/lib/Driver/ToolChains/Hexagon.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/Hexagon.cpp?rev=345446&r1=345445&r2=345446&view=diff == --- cfe/trunk/lib/Driver/ToolChains/Hexagon.cpp (original) +++ cfe/trunk/lib/Driver/ToolChains/Hexagon.cpp Fri Oct 26 21:51:09 2018 @@ -516,9 +516,9 @@ void HexagonToolChain::addClangTargetOpt CC1Args.push_back("-target-feature"); CC1Args.push_back("+reserved-r19"); } - if (!isAutoHVXEnabled(DriverArgs)) { + if (isAutoHVXEnabled(DriverArgs)) { CC1Args.push_back("-mllvm"); -CC1Args.push_back("-hexagon-autohvx=0"); +CC1Args.push_back("-hexagon-autohvx"); } } Modified: cfe/trunk/test/Driver/hexagon-vectorize.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/hexagon-vectorize.c?rev=345446&r1=345445&r2=345446&view=diff == --- cfe/trunk/test/Driver/hexagon-vectorize.c (original) +++ cfe/trunk/test/Driver/hexagon-vectorize.c Fri Oct 26 21:51:09 2018 @@ -3,7 +3,7 @@ // RUN: %clang -target hexagon -fvectorize -fno-vectorize -### %s 2>&1 | FileCheck %s --check-prefix=CHECK-NOVECTOR // RUN: %clang -target hexagon -fvectorize -### %s 2>&1 | FileCheck %s --check-prefix=CHECK-NEEDHVX -// CHECK-DEFAULT: -hexagon-autohvx={{false|0}} -// CHECK-VECTOR-NOT: -hexagon-autohvx={{false|0}} -// CHECK-NOVECTOR: -hexagon-autohvx={{false|0}} +// CHECK-DEFAULT-NOT: hexagon-autohvx +// CHECK-VECTOR: "-mllvm" "-hexagon-autohvx" +// CHECK-NOVECTOR-NOT: hexagon-autohvx // CHECK-NEEDHVX: warning: auto-vectorization requires HVX, use -mhvx to enable it ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D53781: [ASTMatchers] add a matcher for static locals
aaron.ballman accepted this revision. aaron.ballman added a comment. This revision is now accepted and ready to land. LGTM! Do you need someone to commit on your behalf? Repository: rC Clang https://reviews.llvm.org/D53781 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r345459 - [AST] Widen the bit-fields of Stmt to 8 bytes.
Author: brunoricci Date: Sat Oct 27 11:43:27 2018 New Revision: 345459 URL: http://llvm.org/viewvc/llvm-project?rev=345459&view=rev Log: [AST] Widen the bit-fields of Stmt to 8 bytes. Although some classes are using the tail padding of Stmt, most of them are not. In particular the expression classes are not using it since there is Expr in between, and Expr contains a single pointer. This patch widen the bit-fields to Stmt to 8 bytes and move some data from NullStmt, CompoundStmt, LabelStmt, AttributedStmt, SwitchStmt, WhileStmt, DoStmt, ForStmt, GotoStmt, ContinueStmt, BreakStmt and ReturnStmt to the newly available space. In itself this patch do not achieve much but I plan to go through each of the classes in the statement/expression hierarchy and use this newly available space. A quick estimation gives me that this should shrink the size of the statement/expression hierarchy by >10% when parsing all of Boost. Differential Revision: https://reviews.llvm.org/D53604 Reviewed By: rjmccall Modified: cfe/trunk/include/clang/AST/Stmt.h cfe/trunk/lib/AST/Stmt.cpp cfe/trunk/lib/Serialization/ASTReaderStmt.cpp cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Modified: cfe/trunk/include/clang/AST/Stmt.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Stmt.h?rev=345459&r1=345458&r2=345459&view=diff == --- cfe/trunk/include/clang/AST/Stmt.h (original) +++ cfe/trunk/include/clang/AST/Stmt.h Sat Oct 27 11:43:27 2018 @@ -89,6 +89,8 @@ protected: llvm_unreachable("Stmts cannot be released with regular 'delete'."); } + //===--- Statement bitfields classes ---===// + class StmtBitfields { friend class Stmt; @@ -97,12 +99,55 @@ protected: }; enum { NumStmtBits = 8 }; + class NullStmtBitfields { +friend class ASTStmtReader; +friend class ASTStmtWriter; +friend class NullStmt; + +unsigned : NumStmtBits; + +/// True if the null statement was preceded by an empty macro, e.g: +/// @code +/// #define CALL(x) +/// CALL(0); +/// @endcode +unsigned HasLeadingEmptyMacro : 1; + +/// The location of the semi-colon. +SourceLocation SemiLoc; + }; + class CompoundStmtBitfields { +friend class ASTStmtReader; friend class CompoundStmt; unsigned : NumStmtBits; unsigned NumStmts : 32 - NumStmtBits; + +/// The location of the opening "{". +SourceLocation LBraceLoc; + }; + + class LabelStmtBitfields { +friend class LabelStmt; + +unsigned : NumStmtBits; + +SourceLocation IdentLoc; + }; + + class AttributedStmtBitfields { +friend class ASTStmtReader; +friend class AttributedStmt; + +unsigned : NumStmtBits; + +/// Number of attributes. +unsigned NumAttrs : 32 - NumStmtBits; + +/// The location of the attribute. +SourceLocation AttrLoc; }; class IfStmtBitfields { @@ -113,6 +158,81 @@ protected: unsigned IsConstexpr : 1; }; + class SwitchStmtBitfields { +friend class SwitchStmt; + +unsigned : NumStmtBits; + +/// The location of the "switch". +SourceLocation SwitchLoc; + }; + + class WhileStmtBitfields { +friend class WhileStmt; + +unsigned : NumStmtBits; + +/// The location of the "while". +SourceLocation WhileLoc; + }; + + class DoStmtBitfields { +friend class DoStmt; + +unsigned : NumStmtBits; + +/// The location of the "do". +SourceLocation DoLoc; + }; + + class ForStmtBitfields { +friend class ForStmt; + +unsigned : NumStmtBits; + +/// The location of the "for". +SourceLocation ForLoc; + }; + + class GotoStmtBitfields { +friend class GotoStmt; +friend class IndirectGotoStmt; + +unsigned : NumStmtBits; + +/// The location of the "goto". +SourceLocation GotoLoc; + }; + + class ContinueStmtBitfields { +friend class ContinueStmt; + +unsigned : NumStmtBits; + +/// The location of the "continue". +SourceLocation ContinueLoc; + }; + + class BreakStmtBitfields { +friend class BreakStmt; + +unsigned : NumStmtBits; + +/// The location of the "break". +SourceLocation BreakLoc; + }; + + class ReturnStmtBitfields { +friend class ReturnStmt; + +unsigned : NumStmtBits; + +/// The location of the "return". +SourceLocation RetLoc; + }; + + //===--- Expression bitfields classes ---===// + class ExprBitfields { friend class ASTStmtReader; // deserialization friend class AtomicExpr; // ctor @@ -294,9 +414,23 @@ protected: }; union { +// Statements StmtBitfields StmtBits; +NullStmtBitfields NullStmtBits; CompoundStmtBitfields CompoundStmtBits; +LabelStmtBitfields LabelStmtBits; +AttributedStmtBitfields AttributedStmtBits; IfStmtBitfields IfStmtBits; +SwitchStmtBitfields SwitchStmtBits; +WhileStmtBitfields WhileStmtBits; +DoStmtBitfields DoStmtBits; +ForStmtBit
[PATCH] D53604: [AST] Widen the bit-fields of Stmt to 8 bytes
This revision was automatically updated to reflect the committed changes. Closed by commit rL345459: [AST] Widen the bit-fields of Stmt to 8 bytes. (authored by brunoricci, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D53604?vs=170733&id=171405#toc Repository: rL LLVM https://reviews.llvm.org/D53604 Files: cfe/trunk/include/clang/AST/Stmt.h cfe/trunk/lib/AST/Stmt.cpp cfe/trunk/lib/Serialization/ASTReaderStmt.cpp cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Index: cfe/trunk/include/clang/AST/Stmt.h === --- cfe/trunk/include/clang/AST/Stmt.h +++ cfe/trunk/include/clang/AST/Stmt.h @@ -89,20 +89,65 @@ llvm_unreachable("Stmts cannot be released with regular 'delete'."); } + //===--- Statement bitfields classes ---===// + class StmtBitfields { friend class Stmt; /// The statement class. unsigned sClass : 8; }; enum { NumStmtBits = 8 }; + class NullStmtBitfields { +friend class ASTStmtReader; +friend class ASTStmtWriter; +friend class NullStmt; + +unsigned : NumStmtBits; + +/// True if the null statement was preceded by an empty macro, e.g: +/// @code +/// #define CALL(x) +/// CALL(0); +/// @endcode +unsigned HasLeadingEmptyMacro : 1; + +/// The location of the semi-colon. +SourceLocation SemiLoc; + }; + class CompoundStmtBitfields { +friend class ASTStmtReader; friend class CompoundStmt; unsigned : NumStmtBits; unsigned NumStmts : 32 - NumStmtBits; + +/// The location of the opening "{". +SourceLocation LBraceLoc; + }; + + class LabelStmtBitfields { +friend class LabelStmt; + +unsigned : NumStmtBits; + +SourceLocation IdentLoc; + }; + + class AttributedStmtBitfields { +friend class ASTStmtReader; +friend class AttributedStmt; + +unsigned : NumStmtBits; + +/// Number of attributes. +unsigned NumAttrs : 32 - NumStmtBits; + +/// The location of the attribute. +SourceLocation AttrLoc; }; class IfStmtBitfields { @@ -113,6 +158,81 @@ unsigned IsConstexpr : 1; }; + class SwitchStmtBitfields { +friend class SwitchStmt; + +unsigned : NumStmtBits; + +/// The location of the "switch". +SourceLocation SwitchLoc; + }; + + class WhileStmtBitfields { +friend class WhileStmt; + +unsigned : NumStmtBits; + +/// The location of the "while". +SourceLocation WhileLoc; + }; + + class DoStmtBitfields { +friend class DoStmt; + +unsigned : NumStmtBits; + +/// The location of the "do". +SourceLocation DoLoc; + }; + + class ForStmtBitfields { +friend class ForStmt; + +unsigned : NumStmtBits; + +/// The location of the "for". +SourceLocation ForLoc; + }; + + class GotoStmtBitfields { +friend class GotoStmt; +friend class IndirectGotoStmt; + +unsigned : NumStmtBits; + +/// The location of the "goto". +SourceLocation GotoLoc; + }; + + class ContinueStmtBitfields { +friend class ContinueStmt; + +unsigned : NumStmtBits; + +/// The location of the "continue". +SourceLocation ContinueLoc; + }; + + class BreakStmtBitfields { +friend class BreakStmt; + +unsigned : NumStmtBits; + +/// The location of the "break". +SourceLocation BreakLoc; + }; + + class ReturnStmtBitfields { +friend class ReturnStmt; + +unsigned : NumStmtBits; + +/// The location of the "return". +SourceLocation RetLoc; + }; + + //===--- Expression bitfields classes ---===// + class ExprBitfields { friend class ASTStmtReader; // deserialization friend class AtomicExpr; // ctor @@ -294,9 +414,23 @@ }; union { +// Statements StmtBitfields StmtBits; +NullStmtBitfields NullStmtBits; CompoundStmtBitfields CompoundStmtBits; +LabelStmtBitfields LabelStmtBits; +AttributedStmtBitfields AttributedStmtBits; IfStmtBitfields IfStmtBits; +SwitchStmtBitfields SwitchStmtBits; +WhileStmtBitfields WhileStmtBits; +DoStmtBitfields DoStmtBits; +ForStmtBitfields ForStmtBits; +GotoStmtBitfields GotoStmtBits; +ContinueStmtBitfields ContinueStmtBits; +BreakStmtBitfields BreakStmtBits; +ReturnStmtBitfields ReturnStmtBits; + +// Expressions ExprBitfields ExprBits; CharacterLiteralBitfields CharacterLiteralBits; FloatingLiteralBitfields FloatingLiteralBits; @@ -380,7 +514,7 @@ public: Stmt(StmtClass SC) { -static_assert(sizeof(*this) == sizeof(void *), +static_assert(sizeof(*this) <= 8, "changing bitfields changed sizeof(Stmt)"); static_assert(sizeof(*this) % alignof(void *) == 0, "Insufficient alignment!"); @@ -515,9 +649,7 @@ /// isSingleDecl - This method returns true if this DeclStmt refers /// to a single Decl. - bool isSingleDecl() const { -return DG.isSingleD
r345460 - [AST] Refactor PredefinedExpr
Author: brunoricci Date: Sat Oct 27 12:21:19 2018 New Revision: 345460 URL: http://llvm.org/viewvc/llvm-project?rev=345460&view=rev Log: [AST] Refactor PredefinedExpr Make the following changes to PredefinedExpr: 1. Move PredefinedExpr below StringLiteral so that it can use its definition. 2. Rename IdentType to IdentKind to be more in line with clang's conventions, and propagate the change to its users. 3. Move the location and the IdentKind into the newly available space of the bit-fields of Stmt. 4. Only store the function name when needed. When parsing all of Boost, of the 1357 PredefinedExpr 919 have no function name. Differential Revision: https://reviews.llvm.org/D53605 Reviewed By: rjmccall Modified: cfe/trunk/include/clang/AST/Expr.h cfe/trunk/include/clang/AST/Stmt.h cfe/trunk/include/clang/AST/StmtDataCollectors.td cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/AST/ASTDumper.cpp cfe/trunk/lib/AST/ASTImporter.cpp cfe/trunk/lib/AST/Expr.cpp cfe/trunk/lib/AST/StmtPrinter.cpp cfe/trunk/lib/AST/StmtProfile.cpp cfe/trunk/lib/CodeGen/CGExpr.cpp cfe/trunk/lib/CodeGen/CGExprConstant.cpp cfe/trunk/lib/Sema/SemaExpr.cpp cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp cfe/trunk/lib/Sema/TreeTransform.h cfe/trunk/lib/Serialization/ASTReaderStmt.cpp cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Modified: cfe/trunk/include/clang/AST/Expr.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=345460&r1=345459&r2=345460&view=diff == --- cfe/trunk/include/clang/AST/Expr.h (original) +++ cfe/trunk/include/clang/AST/Expr.h Sat Oct 27 12:21:19 2018 @@ -32,6 +32,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/AtomicOrdering.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/TrailingObjects.h" namespace clang { class APValue; @@ -1204,64 +1205,6 @@ public: friend class ASTStmtWriter; }; -/// [C99 6.4.2.2] - A predefined identifier such as __func__. -class PredefinedExpr : public Expr { -public: - enum IdentType { -Func, -Function, -LFunction, // Same as Function, but as wide string. -FuncDName, -FuncSig, -LFuncSig, // Same as FuncSig, but as as wide string -PrettyFunction, -/// The same as PrettyFunction, except that the -/// 'virtual' keyword is omitted for virtual member functions. -PrettyFunctionNoVirtual - }; - -private: - SourceLocation Loc; - IdentType Type; - Stmt *FnName; - -public: - PredefinedExpr(SourceLocation L, QualType FNTy, IdentType IT, - StringLiteral *SL); - - /// Construct an empty predefined expression. - explicit PredefinedExpr(EmptyShell Empty) - : Expr(PredefinedExprClass, Empty), Loc(), Type(Func), FnName(nullptr) {} - - IdentType getIdentType() const { return Type; } - - SourceLocation getLocation() const { return Loc; } - void setLocation(SourceLocation L) { Loc = L; } - - StringLiteral *getFunctionName(); - const StringLiteral *getFunctionName() const { -return const_cast(this)->getFunctionName(); - } - - static StringRef getIdentTypeName(IdentType IT); - static std::string ComputeName(IdentType IT, const Decl *CurrentDecl); - - SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; } - SourceLocation getEndLoc() const LLVM_READONLY { return Loc; } - - static bool classof(const Stmt *T) { -return T->getStmtClass() == PredefinedExprClass; - } - - // Iterators - child_range children() { return child_range(&FnName, &FnName + 1); } - const_child_range children() const { -return const_child_range(&FnName, &FnName + 1); - } - - friend class ASTStmtReader; -}; - /// Used by IntegerLiteral/FloatingLiteral to store the numeric without /// leaking memory. /// @@ -1732,6 +1675,91 @@ public: } }; +/// [C99 6.4.2.2] - A predefined identifier such as __func__. +class PredefinedExpr final +: public Expr, + private llvm::TrailingObjects { + friend class ASTStmtReader; + friend TrailingObjects; + + // PredefinedExpr is optionally followed by a single trailing + // "Stmt *" for the predefined identifier. It is present if and only if + // hasFunctionName() is true and is always a "StringLiteral *". + +public: + enum IdentKind { +Func, +Function, +LFunction, // Same as Function, but as wide string. +FuncDName, +FuncSig, +LFuncSig, // Same as FuncSig, but as as wide string +PrettyFunction, +/// The same as PrettyFunction, except that the +/// 'virtual' keyword is omitted for virtual member functions. +PrettyFunctionNoVirtual + }; + +private: + PredefinedExpr(SourceLocation L, QualType FNTy, IdentKind IK, + StringLiteral *SL); + + explicit PredefinedExpr(EmptyShell Empty, bool HasFunctionName); + + /// True if this PredefinedExpr has storage for a function name. + bool hasFunctionName() const { return Pr
[clang-tools-extra] r345460 - [AST] Refactor PredefinedExpr
Author: brunoricci Date: Sat Oct 27 12:21:19 2018 New Revision: 345460 URL: http://llvm.org/viewvc/llvm-project?rev=345460&view=rev Log: [AST] Refactor PredefinedExpr Make the following changes to PredefinedExpr: 1. Move PredefinedExpr below StringLiteral so that it can use its definition. 2. Rename IdentType to IdentKind to be more in line with clang's conventions, and propagate the change to its users. 3. Move the location and the IdentKind into the newly available space of the bit-fields of Stmt. 4. Only store the function name when needed. When parsing all of Boost, of the 1357 PredefinedExpr 919 have no function name. Differential Revision: https://reviews.llvm.org/D53605 Reviewed By: rjmccall Modified: clang-tools-extra/trunk/clang-tidy/bugprone/LambdaFunctionNameCheck.cpp Modified: clang-tools-extra/trunk/clang-tidy/bugprone/LambdaFunctionNameCheck.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/bugprone/LambdaFunctionNameCheck.cpp?rev=345460&r1=345459&r2=345460&view=diff == --- clang-tools-extra/trunk/clang-tidy/bugprone/LambdaFunctionNameCheck.cpp (original) +++ clang-tools-extra/trunk/clang-tidy/bugprone/LambdaFunctionNameCheck.cpp Sat Oct 27 12:21:19 2018 @@ -73,8 +73,8 @@ void LambdaFunctionNameCheck::registerPP void LambdaFunctionNameCheck::check(const MatchFinder::MatchResult &Result) { const auto *E = Result.Nodes.getNodeAs("E"); - if (E->getIdentType() != PredefinedExpr::Func && - E->getIdentType() != PredefinedExpr::Function) { + if (E->getIdentKind() != PredefinedExpr::Func && + E->getIdentKind() != PredefinedExpr::Function) { // We don't care about other PredefinedExprs. return; } @@ -91,7 +91,7 @@ void LambdaFunctionNameCheck::check(cons "inside a lambda, '%0' expands to the name of the function call " "operator; consider capturing the name of the enclosing function " "explicitly") - << PredefinedExpr::getIdentTypeName(E->getIdentType()); + << PredefinedExpr::getIdentKindName(E->getIdentKind()); } } // namespace bugprone ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D53605: [AST] Refactor PredefinedExpr
This revision was automatically updated to reflect the committed changes. Closed by commit rL345460: [AST] Refactor PredefinedExpr (authored by brunoricci, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D53605?vs=171326&id=171406#toc Repository: rL LLVM https://reviews.llvm.org/D53605 Files: cfe/trunk/include/clang/AST/Expr.h cfe/trunk/include/clang/AST/Stmt.h cfe/trunk/include/clang/AST/StmtDataCollectors.td cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/AST/ASTDumper.cpp cfe/trunk/lib/AST/ASTImporter.cpp cfe/trunk/lib/AST/Expr.cpp cfe/trunk/lib/AST/StmtPrinter.cpp cfe/trunk/lib/AST/StmtProfile.cpp cfe/trunk/lib/CodeGen/CGExpr.cpp cfe/trunk/lib/CodeGen/CGExprConstant.cpp cfe/trunk/lib/Sema/SemaExpr.cpp cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp cfe/trunk/lib/Sema/TreeTransform.h cfe/trunk/lib/Serialization/ASTReaderStmt.cpp cfe/trunk/lib/Serialization/ASTWriterStmt.cpp clang-tools-extra/trunk/clang-tidy/bugprone/LambdaFunctionNameCheck.cpp Index: cfe/trunk/lib/CodeGen/CGExpr.cpp === --- cfe/trunk/lib/CodeGen/CGExpr.cpp +++ cfe/trunk/lib/CodeGen/CGExpr.cpp @@ -2662,7 +2662,7 @@ if (FnName.startswith("\01")) FnName = FnName.substr(1); StringRef NameItems[] = { - PredefinedExpr::getIdentTypeName(E->getIdentType()), FnName}; + PredefinedExpr::getIdentKindName(E->getIdentKind()), FnName}; std::string GVName = llvm::join(NameItems, NameItems + 2, "."); if (auto *BD = dyn_cast_or_null(CurCodeDecl)) { std::string Name = SL->getString(); Index: cfe/trunk/lib/CodeGen/CGExprConstant.cpp === --- cfe/trunk/lib/CodeGen/CGExprConstant.cpp +++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp @@ -1783,7 +1783,7 @@ return cast(Res.getAddress()); } - auto kind = E->getIdentType(); + auto kind = E->getIdentKind(); if (kind == PredefinedExpr::PrettyFunction) { return CGM.GetAddrOfConstantCString("top level", ".tmp"); } Index: cfe/trunk/lib/AST/StmtPrinter.cpp === --- cfe/trunk/lib/AST/StmtPrinter.cpp +++ cfe/trunk/lib/AST/StmtPrinter.cpp @@ -991,7 +991,7 @@ } void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) { - OS << PredefinedExpr::getIdentTypeName(Node->getIdentType()); + OS << PredefinedExpr::getIdentKindName(Node->getIdentKind()); } void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) { Index: cfe/trunk/lib/AST/ASTImporter.cpp === --- cfe/trunk/lib/AST/ASTImporter.cpp +++ cfe/trunk/lib/AST/ASTImporter.cpp @@ -6148,8 +6148,8 @@ StringLiteral *ToFunctionName; std::tie(ToBeginLoc, ToType, ToFunctionName) = *Imp; - return new (Importer.getToContext()) PredefinedExpr( - ToBeginLoc, ToType, E->getIdentType(), ToFunctionName); + return PredefinedExpr::Create(Importer.getToContext(), ToBeginLoc, ToType, +E->getIdentKind(), ToFunctionName); } ExpectedStmt ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) { Index: cfe/trunk/lib/AST/Expr.cpp === --- cfe/trunk/lib/AST/Expr.cpp +++ cfe/trunk/lib/AST/Expr.cpp @@ -458,20 +458,45 @@ return getNameInfo().getEndLoc(); } -PredefinedExpr::PredefinedExpr(SourceLocation L, QualType FNTy, IdentType IT, +PredefinedExpr::PredefinedExpr(SourceLocation L, QualType FNTy, IdentKind IK, StringLiteral *SL) : Expr(PredefinedExprClass, FNTy, VK_LValue, OK_Ordinary, FNTy->isDependentType(), FNTy->isDependentType(), FNTy->isInstantiationDependentType(), - /*ContainsUnexpandedParameterPack=*/false), - Loc(L), Type(IT), FnName(SL) {} - -StringLiteral *PredefinedExpr::getFunctionName() { - return cast_or_null(FnName); + /*ContainsUnexpandedParameterPack=*/false) { + PredefinedExprBits.Kind = IK; + assert((getIdentKind() == IK) && + "IdentKind do not fit in PredefinedExprBitfields!"); + bool HasFunctionName = SL != nullptr; + PredefinedExprBits.HasFunctionName = HasFunctionName; + PredefinedExprBits.Loc = L; + if (HasFunctionName) +setFunctionName(SL); +} + +PredefinedExpr::PredefinedExpr(EmptyShell Empty, bool HasFunctionName) +: Expr(PredefinedExprClass, Empty) { + PredefinedExprBits.HasFunctionName = HasFunctionName; +} + +PredefinedExpr *PredefinedExpr::Create(const ASTContext &Ctx, SourceLocation L, + QualType FNTy, IdentKind IK, + StringLiteral *SL) { + bool HasFunctionName = SL != nullptr; + void *Mem = Ctx.Allocate(totalSizeToAlloc(HasFunctionName), + alignof(PredefinedExpr)); + return new (Mem) PredefinedExpr(L, FNTy, IK, SL); +} + +P
[PATCH] D53263: Fix places where the return type of a FunctionDecl was being used in place of the function type
bobsayshilol added a comment. Ping. https://reviews.llvm.org/D53263 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r345464 - [AST] Only store the needed data in IfStmt
Author: brunoricci Date: Sat Oct 27 14:12:20 2018 New Revision: 345464 URL: http://llvm.org/viewvc/llvm-project?rev=345464&view=rev Log: [AST] Only store the needed data in IfStmt Only store the needed data in IfStmt. This cuts the size of IfStmt by up to 3 pointers + 1 SourceLocation. The order of the children is intentionally kept the same even though it would be more convenient to put the optional trailing objects last. Additionally use the newly available space in the bit-fields of Stmt to store the location of the "if". The result of this is that for the common case of an if statement of the form: if (some_cond) some_statement the size of IfStmt is brought down to 8 bytes + 2 pointers, instead of 8 bytes + 5 pointers + 2 SourceLocation. Differential Revision: https://reviews.llvm.org/D53607 Reviewed By: rjmccall Modified: cfe/trunk/include/clang/AST/Stmt.h cfe/trunk/lib/AST/ASTDumper.cpp cfe/trunk/lib/AST/ASTImporter.cpp cfe/trunk/lib/AST/Stmt.cpp cfe/trunk/lib/Analysis/BodyFarm.cpp cfe/trunk/lib/Sema/SemaStmt.cpp cfe/trunk/lib/Serialization/ASTReaderStmt.cpp cfe/trunk/lib/Serialization/ASTWriterStmt.cpp cfe/trunk/test/Import/if-stmt/test.cpp cfe/trunk/test/Misc/ast-dump-invalid.cpp Modified: cfe/trunk/include/clang/AST/Stmt.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Stmt.h?rev=345464&r1=345463&r2=345464&view=diff == --- cfe/trunk/include/clang/AST/Stmt.h (original) +++ cfe/trunk/include/clang/AST/Stmt.h Sat Oct 27 14:12:20 2018 @@ -151,11 +151,25 @@ protected: }; class IfStmtBitfields { +friend class ASTStmtReader; friend class IfStmt; unsigned : NumStmtBits; +/// True if this if statement is a constexpr if. unsigned IsConstexpr : 1; + +/// True if this if statement has storage for an else statement. +unsigned HasElse : 1; + +/// True if this if statement has storage for a variable declaration. +unsigned HasVar : 1; + +/// True if this if statement has storage for an init statement. +unsigned HasInit : 1; + +/// The location of the "if". +SourceLocation IfLoc; }; class SwitchStmtBitfields { @@ -1100,21 +1114,117 @@ public: }; /// IfStmt - This represents an if/then/else. -class IfStmt : public Stmt { - enum { INIT, VAR, COND, THEN, ELSE, END_EXPR }; - Stmt* SubExprs[END_EXPR]; +class IfStmt final +: public Stmt, + private llvm::TrailingObjects { + friend TrailingObjects; + + // IfStmt is followed by several trailing objects, some of which optional. + // Note that it would be more convenient to put the optional trailing + // objects at then end but this would change the order of the children. + // The trailing objects are in order: + // + // * A "Stmt *" for the init statement. + //Present if and only if hasInitStorage(). + // + // * A "Stmt *" for the condition variable. + //Present if and only if hasVarStorage(). This is in fact a "DeclStmt *". + // + // * A "Stmt *" for the condition. + //Always present. This is in fact a "Expr *". + // + // * A "Stmt *" for the then statement. + //Always present. + // + // * A "Stmt *" for the else statement. + //Present if and only if hasElseStorage(). + // + // * A "SourceLocation" for the location of the "else". + //Present if and only if hasElseStorage(). + enum { InitOffset = 0, ThenOffsetFromCond = 1, ElseOffsetFromCond = 2 }; + enum { NumMandatoryStmtPtr = 2 }; + + unsigned numTrailingObjects(OverloadToken) const { +return NumMandatoryStmtPtr + hasElseStorage() + hasVarStorage() + + hasInitStorage(); + } + + unsigned numTrailingObjects(OverloadToken) const { +return hasElseStorage(); + } + + unsigned initOffset() const { return InitOffset; } + unsigned varOffset() const { return InitOffset + hasInitStorage(); } + unsigned condOffset() const { +return InitOffset + hasInitStorage() + hasVarStorage(); + } + unsigned thenOffset() const { return condOffset() + ThenOffsetFromCond; } + unsigned elseOffset() const { return condOffset() + ElseOffsetFromCond; } + + /// Build an if/then/else statement. + IfStmt(const ASTContext &Ctx, SourceLocation IL, bool IsConstexpr, Stmt *Init, + VarDecl *Var, Expr *Cond, Stmt *Then, SourceLocation EL, Stmt *Else); - SourceLocation IfLoc; - SourceLocation ElseLoc; + /// Build an empty if/then/else statement. + explicit IfStmt(EmptyShell Empty, bool HasElse, bool HasVar, bool HasInit); public: - IfStmt(const ASTContext &C, SourceLocation IL, - bool IsConstexpr, Stmt *init, VarDecl *var, Expr *cond, - Stmt *then, SourceLocation EL = SourceLocation(), - Stmt *elsev = nullptr); + /// Create an IfStmt. + static IfStmt *Create(const ASTContext &Ctx, SourceLocation IL, +bool IsConstexpr, Stmt *Init, VarDecl *Var, Expr *Cond, +
[PATCH] D53607: [AST] Only store the needed data in IfStmt.
This revision was automatically updated to reflect the committed changes. Closed by commit rC345464: [AST] Only store the needed data in IfStmt (authored by brunoricci, committed by ). Repository: rC Clang https://reviews.llvm.org/D53607 Files: include/clang/AST/Stmt.h lib/AST/ASTDumper.cpp lib/AST/ASTImporter.cpp lib/AST/Stmt.cpp lib/Analysis/BodyFarm.cpp lib/Sema/SemaStmt.cpp lib/Serialization/ASTReaderStmt.cpp lib/Serialization/ASTWriterStmt.cpp test/Import/if-stmt/test.cpp test/Misc/ast-dump-invalid.cpp Index: include/clang/AST/Stmt.h === --- include/clang/AST/Stmt.h +++ include/clang/AST/Stmt.h @@ -151,11 +151,25 @@ }; class IfStmtBitfields { +friend class ASTStmtReader; friend class IfStmt; unsigned : NumStmtBits; +/// True if this if statement is a constexpr if. unsigned IsConstexpr : 1; + +/// True if this if statement has storage for an else statement. +unsigned HasElse : 1; + +/// True if this if statement has storage for a variable declaration. +unsigned HasVar : 1; + +/// True if this if statement has storage for an init statement. +unsigned HasInit : 1; + +/// The location of the "if". +SourceLocation IfLoc; }; class SwitchStmtBitfields { @@ -1100,21 +1114,117 @@ }; /// IfStmt - This represents an if/then/else. -class IfStmt : public Stmt { - enum { INIT, VAR, COND, THEN, ELSE, END_EXPR }; - Stmt* SubExprs[END_EXPR]; +class IfStmt final +: public Stmt, + private llvm::TrailingObjects { + friend TrailingObjects; - SourceLocation IfLoc; - SourceLocation ElseLoc; + // IfStmt is followed by several trailing objects, some of which optional. + // Note that it would be more convenient to put the optional trailing + // objects at then end but this would change the order of the children. + // The trailing objects are in order: + // + // * A "Stmt *" for the init statement. + //Present if and only if hasInitStorage(). + // + // * A "Stmt *" for the condition variable. + //Present if and only if hasVarStorage(). This is in fact a "DeclStmt *". + // + // * A "Stmt *" for the condition. + //Always present. This is in fact a "Expr *". + // + // * A "Stmt *" for the then statement. + //Always present. + // + // * A "Stmt *" for the else statement. + //Present if and only if hasElseStorage(). + // + // * A "SourceLocation" for the location of the "else". + //Present if and only if hasElseStorage(). + enum { InitOffset = 0, ThenOffsetFromCond = 1, ElseOffsetFromCond = 2 }; + enum { NumMandatoryStmtPtr = 2 }; + + unsigned numTrailingObjects(OverloadToken) const { +return NumMandatoryStmtPtr + hasElseStorage() + hasVarStorage() + + hasInitStorage(); + } + + unsigned numTrailingObjects(OverloadToken) const { +return hasElseStorage(); + } + + unsigned initOffset() const { return InitOffset; } + unsigned varOffset() const { return InitOffset + hasInitStorage(); } + unsigned condOffset() const { +return InitOffset + hasInitStorage() + hasVarStorage(); + } + unsigned thenOffset() const { return condOffset() + ThenOffsetFromCond; } + unsigned elseOffset() const { return condOffset() + ElseOffsetFromCond; } + + /// Build an if/then/else statement. + IfStmt(const ASTContext &Ctx, SourceLocation IL, bool IsConstexpr, Stmt *Init, + VarDecl *Var, Expr *Cond, Stmt *Then, SourceLocation EL, Stmt *Else); + + /// Build an empty if/then/else statement. + explicit IfStmt(EmptyShell Empty, bool HasElse, bool HasVar, bool HasInit); + +public: + /// Create an IfStmt. + static IfStmt *Create(const ASTContext &Ctx, SourceLocation IL, +bool IsConstexpr, Stmt *Init, VarDecl *Var, Expr *Cond, +Stmt *Then, SourceLocation EL = SourceLocation(), +Stmt *Else = nullptr); + + /// Create an empty IfStmt optionally with storage for an else statement, + /// condition variable and init expression. + static IfStmt *CreateEmpty(const ASTContext &Ctx, bool HasElse, bool HasVar, + bool HasInit); + + /// True if this IfStmt has the storage for an init statement. + bool hasInitStorage() const { return IfStmtBits.HasInit; } -public: - IfStmt(const ASTContext &C, SourceLocation IL, - bool IsConstexpr, Stmt *init, VarDecl *var, Expr *cond, - Stmt *then, SourceLocation EL = SourceLocation(), - Stmt *elsev = nullptr); + /// True if this IfStmt has storage for a variable declaration. + bool hasVarStorage() const { return IfStmtBits.HasVar; } + + /// True if this IfStmt has storage for an else statement. + bool hasElseStorage() const { return IfStmtBits.HasElse; } - /// Build an empty if/then/else statement - explicit IfStmt(EmptyShell Empty) : Stmt(IfStmtClass, Empty) {} + Expr *getCond() { +return reinterpret_cast(getTrailingObjects()[condO
[PATCH] D53704: [ASTImporter] Import overrides before importing the rest of the chain
a_sidorin accepted this revision. a_sidorin added a comment. This revision is now accepted and ready to land. Hello Gabor, The change looks harmless so I think it can be accepted even without tests. Did you encountered the issue while analyzing some real code? Repository: rC Clang https://reviews.llvm.org/D53704 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r345470 - Reapply Pass the nopie flag to the linker when linking with -pg.
Author: brad Date: Sat Oct 27 20:30:18 2018 New Revision: 345470 URL: http://llvm.org/viewvc/llvm-project?rev=345470&view=rev Log: Reapply Pass the nopie flag to the linker when linking with -pg. Modified: cfe/trunk/lib/Driver/ToolChains/OpenBSD.cpp cfe/trunk/test/Driver/openbsd.c Modified: cfe/trunk/lib/Driver/ToolChains/OpenBSD.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/OpenBSD.cpp?rev=345470&r1=345469&r2=345470&view=diff == --- cfe/trunk/lib/Driver/ToolChains/OpenBSD.cpp (original) +++ cfe/trunk/lib/Driver/ToolChains/OpenBSD.cpp Sat Oct 27 20:30:18 2018 @@ -138,7 +138,7 @@ void openbsd::Linker::ConstructJob(Compi if (Args.hasArg(options::OPT_pie)) CmdArgs.push_back("-pie"); - if (Args.hasArg(options::OPT_nopie)) + if (Args.hasArg(options::OPT_nopie) || Args.hasArg(options::OPT_pg)) CmdArgs.push_back("-nopie"); if (Output.isFilename()) { Modified: cfe/trunk/test/Driver/openbsd.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/openbsd.c?rev=345470&r1=345469&r2=345470&view=diff == --- cfe/trunk/test/Driver/openbsd.c (original) +++ cfe/trunk/test/Driver/openbsd.c Sat Oct 27 20:30:18 2018 @@ -12,7 +12,7 @@ // RUN: %clang -no-canonical-prefixes -target i686-pc-openbsd -pg -pthread %s -### 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-PG %s // CHECK-PG: clang{{.*}}" "-cc1" "-triple" "i686-pc-openbsd" -// CHECK-PG: ld{{.*}}" "-e" "__start" "--eh-frame-hdr" "-Bdynamic" "-dynamic-linker" "{{.*}}ld.so" "-o" "a.out" "{{.*}}gcrt0.o" "{{.*}}crtbegin.o" "{{.*}}.o" "-lcompiler_rt" "-lpthread_p" "-lc_p" "-lcompiler_rt" "{{.*}}crtend.o" +// CHECK-PG: ld{{.*}}" "-e" "__start" "--eh-frame-hdr" "-Bdynamic" "-dynamic-linker" "{{.*}}ld.so" "-nopie" "-o" "a.out" "{{.*}}gcrt0.o" "{{.*}}crtbegin.o" "{{.*}}.o" "-lcompiler_rt" "-lpthread_p" "-lc_p" "-lcompiler_rt" "{{.*}}crtend.o" // Check CPU type for MIPS64 // RUN: %clang -target mips64-unknown-openbsd -### -c %s 2>&1 \ ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits