aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/CodeGen/ABIInfo.h2
-rw-r--r--lib/CodeGen/CGDebugInfo.cpp2
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp16
-rw-r--r--lib/CodeGen/CodeGenTypes.cpp4
-rw-r--r--lib/CodeGen/CodeGenTypes.h1
-rw-r--r--lib/CodeGen/ItaniumCXXABI.cpp15
-rw-r--r--lib/CodeGen/TargetInfo.cpp15
-rw-r--r--lib/Driver/ToolChains/Clang.cpp3
-rw-r--r--lib/Format/WhitespaceManager.cpp16
-rw-r--r--lib/Format/WhitespaceManager.h7
-rw-r--r--lib/Frontend/CompilerInvocation.cpp27
11 files changed, 88 insertions, 20 deletions
diff --git a/lib/CodeGen/ABIInfo.h b/lib/CodeGen/ABIInfo.h
index e4dce2f2a004..575506da84d4 100644
--- a/lib/CodeGen/ABIInfo.h
+++ b/lib/CodeGen/ABIInfo.h
@@ -24,6 +24,7 @@ namespace llvm {
namespace clang {
class ASTContext;
+ class CodeGenOptions;
class TargetInfo;
namespace CodeGen {
@@ -68,6 +69,7 @@ namespace swiftcall {
llvm::LLVMContext &getVMContext() const;
const llvm::DataLayout &getDataLayout() const;
const TargetInfo &getTarget() const;
+ const CodeGenOptions &getCodeGenOpts() const;
/// Return the calling convention to use for system runtime
/// functions.
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index c9c450c32e3b..18b1d10a921d 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -3260,7 +3260,7 @@ void CGDebugInfo::EmitInlineFunctionStart(CGBuilderTy &Builder, GlobalDecl GD) {
llvm::DISubprogram *SP = nullptr;
if (FI != SPCache.end())
SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
- if (!SP)
+ if (!SP || !SP->isDefinition())
SP = getFunctionStub(GD);
FnBeginRegionCount.push_back(LexicalBlockStack.size());
LexicalBlockStack.emplace_back(SP);
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index 93a4a3866193..c23b25ea461f 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -22,6 +22,7 @@
#include "CodeGenPGO.h"
#include "TargetInfo.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTLambda.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/StmtCXX.h"
@@ -983,11 +984,22 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,
}
// Check the 'this' pointer once per function, if it's available.
- if (CXXThisValue) {
+ if (CXXABIThisValue) {
SanitizerSet SkippedChecks;
SkippedChecks.set(SanitizerKind::ObjectSize, true);
QualType ThisTy = MD->getThisType(getContext());
- EmitTypeCheck(TCK_Load, Loc, CXXThisValue, ThisTy,
+
+ // If this is the call operator of a lambda with no capture-default, it
+ // may have a static invoker function, which may call this operator with
+ // a null 'this' pointer.
+ if (isLambdaCallOperator(MD) &&
+ cast<CXXRecordDecl>(MD->getParent())->getLambdaCaptureDefault() ==
+ LCD_None)
+ SkippedChecks.set(SanitizerKind::Null, true);
+
+ EmitTypeCheck(isa<CXXConstructorDecl>(MD) ? TCK_ConstructorCall
+ : TCK_MemberCall,
+ Loc, CXXABIThisValue, ThisTy,
getContext().getTypeAlignInChars(ThisTy->getPointeeType()),
SkippedChecks);
}
diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp
index 5ed929135880..9306c4fbaff8 100644
--- a/lib/CodeGen/CodeGenTypes.cpp
+++ b/lib/CodeGen/CodeGenTypes.cpp
@@ -44,6 +44,10 @@ CodeGenTypes::~CodeGenTypes() {
delete &*I++;
}
+const CodeGenOptions &CodeGenTypes::getCodeGenOpts() const {
+ return CGM.getCodeGenOpts();
+}
+
void CodeGenTypes::addRecordTypeName(const RecordDecl *RD,
llvm::StructType *Ty,
StringRef suffix) {
diff --git a/lib/CodeGen/CodeGenTypes.h b/lib/CodeGen/CodeGenTypes.h
index f0b97ebde1c2..9d0e3ded23e4 100644
--- a/lib/CodeGen/CodeGenTypes.h
+++ b/lib/CodeGen/CodeGenTypes.h
@@ -178,6 +178,7 @@ public:
const TargetInfo &getTarget() const { return Target; }
CGCXXABI &getCXXABI() const { return TheCXXABI; }
llvm::LLVMContext &getLLVMContext() { return TheModule.getContext(); }
+ const CodeGenOptions &getCodeGenOpts() const;
/// ConvertType - Convert type T into a llvm::Type.
llvm::Type *ConvertType(QualType T);
diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp
index e7963674fc29..bd4cb9a3667b 100644
--- a/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/lib/CodeGen/ItaniumCXXABI.cpp
@@ -62,9 +62,20 @@ public:
bool classifyReturnType(CGFunctionInfo &FI) const override;
+ bool passClassIndirect(const CXXRecordDecl *RD) const {
+ // Clang <= 4 used the pre-C++11 rule, which ignores move operations.
+ // The PS4 platform ABI follows the behavior of Clang 3.2.
+ if (CGM.getCodeGenOpts().getClangABICompat() <=
+ CodeGenOptions::ClangABI::Ver4 ||
+ CGM.getTriple().getOS() == llvm::Triple::PS4)
+ return RD->hasNonTrivialDestructor() ||
+ RD->hasNonTrivialCopyConstructor();
+ return !canCopyArgument(RD);
+ }
+
RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const override {
// If C++ prohibits us from making a copy, pass by address.
- if (!canCopyArgument(RD))
+ if (passClassIndirect(RD))
return RAA_Indirect;
return RAA_Default;
}
@@ -996,7 +1007,7 @@ bool ItaniumCXXABI::classifyReturnType(CGFunctionInfo &FI) const {
return false;
// If C++ prohibits us from making a copy, return by address.
- if (!canCopyArgument(RD)) {
+ if (passClassIndirect(RD)) {
auto Align = CGM.getContext().getTypeAlignInChars(FI.getReturnType());
FI.getReturnInfo() = ABIArgInfo::getIndirect(Align, /*ByVal=*/false);
return true;
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp
index eb230aad4d35..ece3a407eae3 100644
--- a/lib/CodeGen/TargetInfo.cpp
+++ b/lib/CodeGen/TargetInfo.cpp
@@ -183,7 +183,11 @@ const TargetInfo &ABIInfo::getTarget() const {
return CGT.getTarget();
}
-bool ABIInfo:: isAndroid() const { return getTarget().getTriple().isAndroid(); }
+const CodeGenOptions &ABIInfo::getCodeGenOpts() const {
+ return CGT.getCodeGenOpts();
+}
+
+bool ABIInfo::isAndroid() const { return getTarget().getTriple().isAndroid(); }
bool ABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const {
return false;
@@ -2095,9 +2099,14 @@ class X86_64ABIInfo : public SwiftABIInfo {
return !getTarget().getTriple().isOSDarwin();
}
- /// GCC classifies <1 x long long> as SSE but compatibility with older clang
- // compilers require us to classify it as INTEGER.
+ /// GCC classifies <1 x long long> as SSE but some platform ABIs choose to
+ /// classify it as INTEGER (for compatibility with older clang compilers).
bool classifyIntegerMMXAsSSE() const {
+ // Clang <= 3.8 did not do this.
+ if (getCodeGenOpts().getClangABICompat() <=
+ CodeGenOptions::ClangABI::Ver3_8)
+ return false;
+
const llvm::Triple &Triple = getTarget().getTriple();
if (Triple.isOSDarwin() || Triple.getOS() == llvm::Triple::PS4)
return false;
diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp
index baf7a93d2d92..6a6b90f86825 100644
--- a/lib/Driver/ToolChains/Clang.cpp
+++ b/lib/Driver/ToolChains/Clang.cpp
@@ -2855,6 +2855,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
addPGOAndCoverageFlags(C, D, Output, Args, CmdArgs);
+ if (auto *ABICompatArg = Args.getLastArg(options::OPT_fclang_abi_compat_EQ))
+ ABICompatArg->render(Args, CmdArgs);
+
// Add runtime flag for PS4 when PGO or Coverage are enabled.
if (getToolChain().getTriple().isPS4CPU())
PS4cpu::addProfileRTArgs(getToolChain(), Args, CmdArgs);
diff --git a/lib/Format/WhitespaceManager.cpp b/lib/Format/WhitespaceManager.cpp
index b1a5f1eab552..377ec3a681b6 100644
--- a/lib/Format/WhitespaceManager.cpp
+++ b/lib/Format/WhitespaceManager.cpp
@@ -246,12 +246,12 @@ AlignTokenSequence(unsigned Start, unsigned End, unsigned Column, F &&Matches,
for (unsigned i = Start; i != End; ++i) {
if (ScopeStack.size() != 0 &&
- Changes[i].nestingAndIndentLevel() <
- Changes[ScopeStack.back()].nestingAndIndentLevel())
+ Changes[i].indentAndNestingLevel() <
+ Changes[ScopeStack.back()].indentAndNestingLevel())
ScopeStack.pop_back();
- if (i != Start && Changes[i].nestingAndIndentLevel() >
- Changes[i - 1].nestingAndIndentLevel())
+ if (i != Start && Changes[i].indentAndNestingLevel() >
+ Changes[i - 1].indentAndNestingLevel())
ScopeStack.push_back(i);
bool InsideNestedScope = ScopeStack.size() != 0;
@@ -327,8 +327,8 @@ static unsigned AlignTokens(const FormatStyle &Style, F &&Matches,
// Measure the scope level (i.e. depth of (), [], {}) of the first token, and
// abort when we hit any token in a higher scope than the starting one.
- auto NestingAndIndentLevel = StartAt < Changes.size()
- ? Changes[StartAt].nestingAndIndentLevel()
+ auto IndentAndNestingLevel = StartAt < Changes.size()
+ ? Changes[StartAt].indentAndNestingLevel()
: std::pair<unsigned, unsigned>(0, 0);
// Keep track of the number of commas before the matching tokens, we will only
@@ -359,7 +359,7 @@ static unsigned AlignTokens(const FormatStyle &Style, F &&Matches,
unsigned i = StartAt;
for (unsigned e = Changes.size(); i != e; ++i) {
- if (Changes[i].nestingAndIndentLevel() < NestingAndIndentLevel)
+ if (Changes[i].indentAndNestingLevel() < IndentAndNestingLevel)
break;
if (Changes[i].NewlinesBefore != 0) {
@@ -375,7 +375,7 @@ static unsigned AlignTokens(const FormatStyle &Style, F &&Matches,
if (Changes[i].Tok->is(tok::comma)) {
++CommasBeforeMatch;
- } else if (Changes[i].nestingAndIndentLevel() > NestingAndIndentLevel) {
+ } else if (Changes[i].indentAndNestingLevel() > IndentAndNestingLevel) {
// Call AlignTokens recursively, skipping over this scope block.
unsigned StoppedAt = AlignTokens(Style, Matches, Changes, i);
i = StoppedAt - 1;
diff --git a/lib/Format/WhitespaceManager.h b/lib/Format/WhitespaceManager.h
index 50df59d09641..4e78ab43abaf 100644
--- a/lib/Format/WhitespaceManager.h
+++ b/lib/Format/WhitespaceManager.h
@@ -154,12 +154,11 @@ public:
const Change *StartOfBlockComment;
int IndentationOffset;
- // A combination of nesting level and indent level, which are used in
+ // A combination of indent level and nesting level, which are used in
// tandem to compute lexical scope, for the purposes of deciding
// when to stop consecutive alignment runs.
- std::pair<unsigned, unsigned>
- nestingAndIndentLevel() const {
- return std::make_pair(Tok->NestingLevel, Tok->IndentLevel);
+ std::pair<unsigned, unsigned> indentAndNestingLevel() const {
+ return std::make_pair(Tok->IndentLevel, Tok->NestingLevel);
}
};
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index b2c14554a4b5..0d0869c815d3 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -573,6 +573,33 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
if (!Opts.ProfileInstrumentUsePath.empty())
setPGOUseInstrumentor(Opts, Opts.ProfileInstrumentUsePath);
+ if (Arg *A = Args.getLastArg(OPT_fclang_abi_compat_EQ)) {
+ Opts.setClangABICompat(CodeGenOptions::ClangABI::Latest);
+
+ StringRef Ver = A->getValue();
+ std::pair<StringRef, StringRef> VerParts = Ver.split('.');
+ unsigned Major, Minor = 0;
+
+ // Check the version number is valid: either 3.x (0 <= x <= 9) or
+ // y or y.0 (4 <= y <= current version).
+ if (!VerParts.first.startswith("0") &&
+ !VerParts.first.getAsInteger(10, Major) &&
+ 3 <= Major && Major <= CLANG_VERSION_MAJOR &&
+ (Major == 3 ? VerParts.second.size() == 1 &&
+ !VerParts.second.getAsInteger(10, Minor)
+ : VerParts.first.size() == Ver.size() ||
+ VerParts.second == "0")) {
+ // Got a valid version number.
+ if (Major == 3 && Minor <= 8)
+ Opts.setClangABICompat(CodeGenOptions::ClangABI::Ver3_8);
+ else if (Major <= 4)
+ Opts.setClangABICompat(CodeGenOptions::ClangABI::Ver4);
+ } else if (Ver != "latest") {
+ Diags.Report(diag::err_drv_invalid_value)
+ << A->getAsString(Args) << A->getValue();
+ }
+ }
+
Opts.CoverageMapping =
Args.hasFlag(OPT_fcoverage_mapping, OPT_fno_coverage_mapping, false);
Opts.DumpCoverageMapping = Args.hasArg(OPT_dump_coverage_mapping);