aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-04-20 21:20:51 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-04-20 21:20:51 +0000
commit583e75cce441388bc562fa225d23499261a0091e (patch)
tree5944a7c248d4a8c858db45abc3444eb69270a3c8 /lib
parent7442d6faa2719e4e7d33a7021c406c5a4facd74d (diff)
downloadsrc-583e75cce441388bc562fa225d23499261a0091e.tar.gz
src-583e75cce441388bc562fa225d23499261a0091e.zip
Vendor import of clang trunk r300890:vendor/clang/clang-trunk-r300890
Notes
Notes: svn path=/vendor/clang/dist/; revision=317220 svn path=/vendor/clang/clang-trunk-r300890/; revision=317221; tag=vendor/clang/clang-trunk-r300890
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/ASTContext.cpp6
-rw-r--r--lib/AST/Decl.cpp4
-rw-r--r--lib/AST/DeclPrinter.cpp11
-rw-r--r--lib/AST/ExternalASTMerger.cpp39
-rw-r--r--lib/AST/ItaniumMangle.cpp4
-rw-r--r--lib/AST/StmtOpenMP.cpp98
-rw-r--r--lib/ASTMatchers/Dynamic/Registry.cpp1
-rw-r--r--lib/Basic/Attributes.cpp11
-rw-r--r--lib/Basic/OpenMPKinds.cpp6
-rw-r--r--lib/Basic/Targets.cpp9
-rw-r--r--lib/CodeGen/BackendUtil.cpp15
-rw-r--r--lib/CodeGen/CGCall.cpp83
-rw-r--r--lib/CodeGen/CGCall.h1
-rw-r--r--lib/CodeGen/CGDebugInfo.cpp39
-rw-r--r--lib/CodeGen/CGDecl.cpp8
-rw-r--r--lib/CodeGen/CGExpr.cpp38
-rw-r--r--lib/CodeGen/CGExprConstant.cpp6
-rw-r--r--lib/CodeGen/CGObjC.cpp18
-rw-r--r--lib/CodeGen/CGStmt.cpp2
-rw-r--r--lib/CodeGen/CGVTables.cpp7
-rw-r--r--lib/CodeGen/CodeGenModule.cpp13
-rw-r--r--lib/CodeGen/CodeGenModule.h7
-rw-r--r--lib/CodeGen/CodeGenTypeCache.h6
-rw-r--r--lib/CodeGen/ModuleBuilder.cpp2
-rw-r--r--lib/Driver/SanitizerArgs.cpp46
-rw-r--r--lib/Driver/ToolChains/Clang.cpp36
-rw-r--r--lib/Driver/ToolChains/CommonArgs.cpp23
-rw-r--r--lib/Driver/ToolChains/CommonArgs.h6
-rw-r--r--lib/Driver/ToolChains/Gnu.cpp38
-rw-r--r--lib/Driver/ToolChains/MinGW.cpp24
-rw-r--r--lib/Driver/ToolChains/MinGW.h1
-rw-r--r--lib/Format/FormatTokenLexer.cpp3
-rw-r--r--lib/Format/TokenAnnotator.cpp7
-rw-r--r--lib/Frontend/CompilerInvocation.cpp5
-rw-r--r--lib/Headers/smmintrin.h239
-rw-r--r--lib/Headers/xmmintrin.h2
-rw-r--r--lib/Index/CommentToXML.cpp4
-rw-r--r--lib/Index/IndexDecl.cpp14
-rw-r--r--lib/Index/IndexSymbol.cpp2
-rw-r--r--lib/Index/IndexTypeSourceInfo.cpp5
-rw-r--r--lib/Index/IndexingContext.cpp1
-rw-r--r--lib/Index/IndexingContext.h3
-rw-r--r--lib/Lex/Lexer.cpp67
-rw-r--r--lib/Lex/ModuleMap.cpp3
-rw-r--r--lib/Lex/PPLexerChange.cpp5
-rw-r--r--lib/Parse/ParsePragma.cpp534
-rw-r--r--lib/Parse/ParseStmt.cpp4
-rw-r--r--lib/Parse/Parser.cpp10
-rw-r--r--lib/Sema/AttributeList.cpp21
-rw-r--r--lib/Sema/JumpDiagnostics.cpp9
-rw-r--r--lib/Sema/Sema.cpp67
-rw-r--r--lib/Sema/SemaAttr.cpp213
-rw-r--r--lib/Sema/SemaCXXScopeSpec.cpp2
-rw-r--r--lib/Sema/SemaChecking.cpp4
-rw-r--r--lib/Sema/SemaCoroutine.cpp85
-rw-r--r--lib/Sema/SemaDecl.cpp5
-rw-r--r--lib/Sema/SemaDeclAttr.cpp28
-rw-r--r--lib/Sema/SemaDeclCXX.cpp2
-rw-r--r--lib/Sema/SemaDeclObjC.cpp13
-rw-r--r--lib/Sema/SemaExpr.cpp6
-rw-r--r--lib/Sema/SemaOpenMP.cpp88
-rw-r--r--lib/Sema/SemaStmt.cpp1
-rw-r--r--lib/Sema/SemaTemplate.cpp21
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp7
-rw-r--r--lib/Serialization/ASTReaderStmt.cpp7
-rw-r--r--lib/Serialization/ASTWriterStmt.cpp7
66 files changed, 1530 insertions, 572 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 7b337b061a03..4626052a8acb 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -9414,10 +9414,8 @@ createDynTypedNode(const NestedNameSpecifierLoc &Node) {
if (!NodeOrVector.template is<ASTContext::ParentVector *>()) {
auto *Vector = new ASTContext::ParentVector(
1, getSingleDynTypedNodeFromParentMap(NodeOrVector));
- if (auto *Node =
- NodeOrVector
- .template dyn_cast<ast_type_traits::DynTypedNode *>())
- delete Node;
+ delete NodeOrVector
+ .template dyn_cast<ast_type_traits::DynTypedNode *>();
NodeOrVector = Vector;
}
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 2b22e5bb50a5..094e8dcff088 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -3003,9 +3003,7 @@ SourceRange FunctionDecl::getExceptionSpecSourceRange() const {
const Attr *FunctionDecl::getUnusedResultAttr() const {
QualType RetType = getReturnType();
if (RetType->isRecordType()) {
- const CXXRecordDecl *Ret = RetType->getAsCXXRecordDecl();
- const auto *MD = dyn_cast<CXXMethodDecl>(this);
- if (Ret && !(MD && MD->getCorrespondingMethodInClass(Ret, true))) {
+ if (const CXXRecordDecl *Ret = RetType->getAsCXXRecordDecl()) {
if (const auto *R = Ret->getAttr<WarnUnusedResultAttr>())
return R;
}
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index 5d841a197f26..bc8a34c93653 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/lib/AST/DeclPrinter.cpp
@@ -478,6 +478,11 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
if (D->isFunctionTemplateSpecialization())
Out << "template<> ";
+ else if (!D->getDescribedFunctionTemplate()) {
+ for (unsigned I = 0, NumTemplateParams = D->getNumTemplateParameterLists();
+ I < NumTemplateParams; ++I)
+ printTemplateParameters(D->getTemplateParameterList(I));
+ }
CXXConstructorDecl *CDecl = dyn_cast<CXXConstructorDecl>(D);
CXXConversionDecl *ConversionDecl = dyn_cast<CXXConversionDecl>(D);
@@ -1055,6 +1060,12 @@ void DeclPrinter::VisitTemplateDecl(const TemplateDecl *D) {
void DeclPrinter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
prettyPrintPragmas(D->getTemplatedDecl());
+ // Print any leading template parameter lists.
+ if (const FunctionDecl *FD = D->getTemplatedDecl()) {
+ for (unsigned I = 0, NumTemplateParams = FD->getNumTemplateParameterLists();
+ I < NumTemplateParams; ++I)
+ printTemplateParameters(FD->getTemplateParameterList(I));
+ }
VisitRedeclarableTemplateDecl(D);
// Never print "instantiations" for deduction guides (they don't really
diff --git a/lib/AST/ExternalASTMerger.cpp b/lib/AST/ExternalASTMerger.cpp
index 2d4d0185ff2a..8849cfc3c80b 100644
--- a/lib/AST/ExternalASTMerger.cpp
+++ b/lib/AST/ExternalASTMerger.cpp
@@ -89,25 +89,21 @@ bool IsForwardDeclaration(Decl *D) {
}
}
+template <typename CallbackType>
void ForEachMatchingDC(
const DeclContext *DC,
llvm::ArrayRef<ExternalASTMerger::ImporterPair> Importers,
- std::function<void(const ExternalASTMerger::ImporterPair &IP,
- Source<const DeclContext *> SourceDC)>
- Callback) {
+ CallbackType Callback) {
for (const ExternalASTMerger::ImporterPair &IP : Importers) {
- Source<TranslationUnitDecl *> SourceTU(
- IP.Forward->getFromContext().getTranslationUnitDecl());
- Source<const DeclContext *> SourceDC =
- LookupSameContext(SourceTU, DC, *IP.Reverse);
- if (SourceDC.get()) {
+ Source<TranslationUnitDecl *> SourceTU =
+ IP.Forward->getFromContext().getTranslationUnitDecl();
+ if (auto SourceDC = LookupSameContext(SourceTU, DC, *IP.Reverse))
Callback(IP, SourceDC);
- }
}
}
bool HasDeclOfSameType(llvm::ArrayRef<Candidate> Decls, const Candidate &C) {
- return std::any_of(Decls.begin(), Decls.end(), [&C](const Candidate &D) {
+ return llvm::any_of(Decls, [&](const Candidate &D) {
return C.first.get()->getKind() == D.first.get()->getKind();
});
}
@@ -139,15 +135,15 @@ bool ExternalASTMerger::FindExternalVisibleDeclsByName(const DeclContext *DC,
}
};
- ForEachMatchingDC(DC, Importers, [Name, &FilterFoundDecl](
- const ImporterPair &IP,
- Source<const DeclContext *> SourceDC) {
- DeclarationName FromName = IP.Reverse->Import(Name);
- DeclContextLookupResult Result = SourceDC.get()->lookup(FromName);
- for (NamedDecl *FromD : Result) {
- FilterFoundDecl(std::make_pair(FromD, IP.Forward.get()));
- }
- });
+ ForEachMatchingDC(
+ DC, Importers,
+ [&](const ImporterPair &IP, Source<const DeclContext *> SourceDC) {
+ DeclarationName FromName = IP.Reverse->Import(Name);
+ DeclContextLookupResult Result = SourceDC.get()->lookup(FromName);
+ for (NamedDecl *FromD : Result) {
+ FilterFoundDecl(std::make_pair(FromD, IP.Forward.get()));
+ }
+ });
llvm::ArrayRef<Candidate> DeclsToReport =
CompleteDecls.empty() ? ForwardDecls : CompleteDecls;
@@ -170,15 +166,14 @@ void ExternalASTMerger::FindExternalLexicalDecls(
const DeclContext *DC, llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
SmallVectorImpl<Decl *> &Result) {
ForEachMatchingDC(
- DC, Importers, [DC, IsKindWeWant](const ImporterPair &IP,
- Source<const DeclContext *> SourceDC) {
+ DC, Importers,
+ [&](const ImporterPair &IP, Source<const DeclContext *> SourceDC) {
for (const Decl *SourceDecl : SourceDC.get()->decls()) {
if (IsKindWeWant(SourceDecl->getKind())) {
Decl *ImportedDecl =
IP.Forward->Import(const_cast<Decl *>(SourceDecl));
assert(ImportedDecl->getDeclContext() == DC);
(void)ImportedDecl;
- (void)DC;
}
}
});
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index 29fcdd7be924..7db0b4d8e4ff 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -1455,10 +1455,12 @@ void CXXNameMangler::mangleNestedName(const NamedDecl *ND,
Out << 'N';
if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(ND)) {
Qualifiers MethodQuals =
- Qualifiers::fromCVRMask(Method->getTypeQualifiers());
+ Qualifiers::fromCVRUMask(Method->getTypeQualifiers());
// We do not consider restrict a distinguishing attribute for overloading
// purposes so we must not mangle it.
MethodQuals.removeRestrict();
+ // __unaligned is not currently mangled in any way, so remove it.
+ MethodQuals.removeUnaligned();
mangleQualifiers(MethodQuals);
mangleRefQualifier(Method->getRefQualifier());
}
diff --git a/lib/AST/StmtOpenMP.cpp b/lib/AST/StmtOpenMP.cpp
index a812884cd927..cccb2f075b65 100644
--- a/lib/AST/StmtOpenMP.cpp
+++ b/lib/AST/StmtOpenMP.cpp
@@ -147,10 +147,6 @@ OMPForDirective::Create(const ASTContext &C, SourceLocation StartLoc,
Dir->setNextLowerBound(Exprs.NLB);
Dir->setNextUpperBound(Exprs.NUB);
Dir->setNumIterations(Exprs.NumIterations);
- Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
- Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
- Dir->setDistInc(Exprs.DistInc);
- Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
Dir->setCounters(Exprs.Counters);
Dir->setPrivateCounters(Exprs.PrivateCounters);
Dir->setInits(Exprs.Inits);
@@ -201,10 +197,6 @@ OMPForSimdDirective::Create(const ASTContext &C, SourceLocation StartLoc,
Dir->setNextLowerBound(Exprs.NLB);
Dir->setNextUpperBound(Exprs.NUB);
Dir->setNumIterations(Exprs.NumIterations);
- Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
- Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
- Dir->setDistInc(Exprs.DistInc);
- Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
Dir->setCounters(Exprs.Counters);
Dir->setPrivateCounters(Exprs.PrivateCounters);
Dir->setInits(Exprs.Inits);
@@ -368,10 +360,6 @@ OMPParallelForDirective *OMPParallelForDirective::Create(
Dir->setNextLowerBound(Exprs.NLB);
Dir->setNextUpperBound(Exprs.NUB);
Dir->setNumIterations(Exprs.NumIterations);
- Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
- Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
- Dir->setDistInc(Exprs.DistInc);
- Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
Dir->setCounters(Exprs.Counters);
Dir->setPrivateCounters(Exprs.PrivateCounters);
Dir->setInits(Exprs.Inits);
@@ -421,10 +409,6 @@ OMPParallelForSimdDirective *OMPParallelForSimdDirective::Create(
Dir->setNextLowerBound(Exprs.NLB);
Dir->setNextUpperBound(Exprs.NUB);
Dir->setNumIterations(Exprs.NumIterations);
- Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
- Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
- Dir->setDistInc(Exprs.DistInc);
- Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
Dir->setCounters(Exprs.Counters);
Dir->setPrivateCounters(Exprs.PrivateCounters);
Dir->setInits(Exprs.Inits);
@@ -759,10 +743,6 @@ OMPTargetParallelForDirective *OMPTargetParallelForDirective::Create(
Dir->setNextLowerBound(Exprs.NLB);
Dir->setNextUpperBound(Exprs.NUB);
Dir->setNumIterations(Exprs.NumIterations);
- Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
- Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
- Dir->setDistInc(Exprs.DistInc);
- Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
Dir->setCounters(Exprs.Counters);
Dir->setPrivateCounters(Exprs.PrivateCounters);
Dir->setInits(Exprs.Inits);
@@ -904,10 +884,6 @@ OMPTaskLoopDirective *OMPTaskLoopDirective::Create(
Dir->setNextLowerBound(Exprs.NLB);
Dir->setNextUpperBound(Exprs.NUB);
Dir->setNumIterations(Exprs.NumIterations);
- Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
- Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
- Dir->setDistInc(Exprs.DistInc);
- Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
Dir->setCounters(Exprs.Counters);
Dir->setPrivateCounters(Exprs.PrivateCounters);
Dir->setInits(Exprs.Inits);
@@ -957,10 +933,6 @@ OMPTaskLoopSimdDirective *OMPTaskLoopSimdDirective::Create(
Dir->setNextLowerBound(Exprs.NLB);
Dir->setNextUpperBound(Exprs.NUB);
Dir->setNumIterations(Exprs.NumIterations);
- Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
- Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
- Dir->setDistInc(Exprs.DistInc);
- Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
Dir->setCounters(Exprs.Counters);
Dir->setPrivateCounters(Exprs.PrivateCounters);
Dir->setInits(Exprs.Inits);
@@ -1009,10 +981,6 @@ OMPDistributeDirective *OMPDistributeDirective::Create(
Dir->setNextLowerBound(Exprs.NLB);
Dir->setNextUpperBound(Exprs.NUB);
Dir->setNumIterations(Exprs.NumIterations);
- Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
- Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
- Dir->setDistInc(Exprs.DistInc);
- Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
Dir->setCounters(Exprs.Counters);
Dir->setPrivateCounters(Exprs.PrivateCounters);
Dir->setInits(Exprs.Inits);
@@ -1095,6 +1063,13 @@ OMPDistributeParallelForDirective *OMPDistributeParallelForDirective::Create(
Dir->setUpdates(Exprs.Updates);
Dir->setFinals(Exprs.Finals);
Dir->setPreInits(Exprs.PreInits);
+ Dir->setCombinedLowerBoundVariable(Exprs.DistCombinedFields.LB);
+ Dir->setCombinedUpperBoundVariable(Exprs.DistCombinedFields.UB);
+ Dir->setCombinedEnsureUpperBound(Exprs.DistCombinedFields.EUB);
+ Dir->setCombinedInit(Exprs.DistCombinedFields.Init);
+ Dir->setCombinedCond(Exprs.DistCombinedFields.Cond);
+ Dir->setCombinedNextLowerBound(Exprs.DistCombinedFields.NLB);
+ Dir->setCombinedNextUpperBound(Exprs.DistCombinedFields.NUB);
return Dir;
}
@@ -1153,6 +1128,13 @@ OMPDistributeParallelForSimdDirective::Create(
Dir->setUpdates(Exprs.Updates);
Dir->setFinals(Exprs.Finals);
Dir->setPreInits(Exprs.PreInits);
+ Dir->setCombinedLowerBoundVariable(Exprs.DistCombinedFields.LB);
+ Dir->setCombinedUpperBoundVariable(Exprs.DistCombinedFields.UB);
+ Dir->setCombinedEnsureUpperBound(Exprs.DistCombinedFields.EUB);
+ Dir->setCombinedInit(Exprs.DistCombinedFields.Init);
+ Dir->setCombinedCond(Exprs.DistCombinedFields.Cond);
+ Dir->setCombinedNextLowerBound(Exprs.DistCombinedFields.NLB);
+ Dir->setCombinedNextUpperBound(Exprs.DistCombinedFields.NUB);
return Dir;
}
@@ -1200,10 +1182,6 @@ OMPDistributeSimdDirective *OMPDistributeSimdDirective::Create(
Dir->setNextLowerBound(Exprs.NLB);
Dir->setNextUpperBound(Exprs.NUB);
Dir->setNumIterations(Exprs.NumIterations);
- Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
- Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
- Dir->setDistInc(Exprs.DistInc);
- Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
Dir->setCounters(Exprs.Counters);
Dir->setPrivateCounters(Exprs.PrivateCounters);
Dir->setInits(Exprs.Inits);
@@ -1256,10 +1234,6 @@ OMPTargetParallelForSimdDirective *OMPTargetParallelForSimdDirective::Create(
Dir->setNextLowerBound(Exprs.NLB);
Dir->setNextUpperBound(Exprs.NUB);
Dir->setNumIterations(Exprs.NumIterations);
- Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
- Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
- Dir->setDistInc(Exprs.DistInc);
- Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
Dir->setCounters(Exprs.Counters);
Dir->setPrivateCounters(Exprs.PrivateCounters);
Dir->setInits(Exprs.Inits);
@@ -1352,10 +1326,6 @@ OMPTeamsDistributeDirective *OMPTeamsDistributeDirective::Create(
Dir->setNextLowerBound(Exprs.NLB);
Dir->setNextUpperBound(Exprs.NUB);
Dir->setNumIterations(Exprs.NumIterations);
- Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
- Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
- Dir->setDistInc(Exprs.DistInc);
- Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
Dir->setCounters(Exprs.Counters);
Dir->setPrivateCounters(Exprs.PrivateCounters);
Dir->setInits(Exprs.Inits);
@@ -1407,10 +1377,6 @@ OMPTeamsDistributeSimdDirective *OMPTeamsDistributeSimdDirective::Create(
Dir->setNextLowerBound(Exprs.NLB);
Dir->setNextUpperBound(Exprs.NUB);
Dir->setNumIterations(Exprs.NumIterations);
- Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
- Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
- Dir->setDistInc(Exprs.DistInc);
- Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
Dir->setCounters(Exprs.Counters);
Dir->setPrivateCounters(Exprs.PrivateCounters);
Dir->setInits(Exprs.Inits);
@@ -1474,6 +1440,13 @@ OMPTeamsDistributeParallelForSimdDirective::Create(
Dir->setUpdates(Exprs.Updates);
Dir->setFinals(Exprs.Finals);
Dir->setPreInits(Exprs.PreInits);
+ Dir->setCombinedLowerBoundVariable(Exprs.DistCombinedFields.LB);
+ Dir->setCombinedUpperBoundVariable(Exprs.DistCombinedFields.UB);
+ Dir->setCombinedEnsureUpperBound(Exprs.DistCombinedFields.EUB);
+ Dir->setCombinedInit(Exprs.DistCombinedFields.Init);
+ Dir->setCombinedCond(Exprs.DistCombinedFields.Cond);
+ Dir->setCombinedNextLowerBound(Exprs.DistCombinedFields.NLB);
+ Dir->setCombinedNextUpperBound(Exprs.DistCombinedFields.NUB);
return Dir;
}
@@ -1534,6 +1507,13 @@ OMPTeamsDistributeParallelForDirective::Create(
Dir->setUpdates(Exprs.Updates);
Dir->setFinals(Exprs.Finals);
Dir->setPreInits(Exprs.PreInits);
+ Dir->setCombinedLowerBoundVariable(Exprs.DistCombinedFields.LB);
+ Dir->setCombinedUpperBoundVariable(Exprs.DistCombinedFields.UB);
+ Dir->setCombinedEnsureUpperBound(Exprs.DistCombinedFields.EUB);
+ Dir->setCombinedInit(Exprs.DistCombinedFields.Init);
+ Dir->setCombinedCond(Exprs.DistCombinedFields.Cond);
+ Dir->setCombinedNextLowerBound(Exprs.DistCombinedFields.NLB);
+ Dir->setCombinedNextUpperBound(Exprs.DistCombinedFields.NUB);
return Dir;
}
@@ -1606,10 +1586,6 @@ OMPTargetTeamsDistributeDirective *OMPTargetTeamsDistributeDirective::Create(
Dir->setNextLowerBound(Exprs.NLB);
Dir->setNextUpperBound(Exprs.NUB);
Dir->setNumIterations(Exprs.NumIterations);
- Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
- Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
- Dir->setDistInc(Exprs.DistInc);
- Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
Dir->setCounters(Exprs.Counters);
Dir->setPrivateCounters(Exprs.PrivateCounters);
Dir->setInits(Exprs.Inits);
@@ -1676,6 +1652,13 @@ OMPTargetTeamsDistributeParallelForDirective::Create(
Dir->setUpdates(Exprs.Updates);
Dir->setFinals(Exprs.Finals);
Dir->setPreInits(Exprs.PreInits);
+ Dir->setCombinedLowerBoundVariable(Exprs.DistCombinedFields.LB);
+ Dir->setCombinedUpperBoundVariable(Exprs.DistCombinedFields.UB);
+ Dir->setCombinedEnsureUpperBound(Exprs.DistCombinedFields.EUB);
+ Dir->setCombinedInit(Exprs.DistCombinedFields.Init);
+ Dir->setCombinedCond(Exprs.DistCombinedFields.Cond);
+ Dir->setCombinedNextLowerBound(Exprs.DistCombinedFields.NLB);
+ Dir->setCombinedNextUpperBound(Exprs.DistCombinedFields.NUB);
return Dir;
}
@@ -1739,6 +1722,13 @@ OMPTargetTeamsDistributeParallelForSimdDirective::Create(
Dir->setUpdates(Exprs.Updates);
Dir->setFinals(Exprs.Finals);
Dir->setPreInits(Exprs.PreInits);
+ Dir->setCombinedLowerBoundVariable(Exprs.DistCombinedFields.LB);
+ Dir->setCombinedUpperBoundVariable(Exprs.DistCombinedFields.UB);
+ Dir->setCombinedEnsureUpperBound(Exprs.DistCombinedFields.EUB);
+ Dir->setCombinedInit(Exprs.DistCombinedFields.Init);
+ Dir->setCombinedCond(Exprs.DistCombinedFields.Cond);
+ Dir->setCombinedNextLowerBound(Exprs.DistCombinedFields.NLB);
+ Dir->setCombinedNextUpperBound(Exprs.DistCombinedFields.NUB);
return Dir;
}
@@ -1789,10 +1779,6 @@ OMPTargetTeamsDistributeSimdDirective::Create(
Dir->setNextLowerBound(Exprs.NLB);
Dir->setNextUpperBound(Exprs.NUB);
Dir->setNumIterations(Exprs.NumIterations);
- Dir->setPrevLowerBoundVariable(Exprs.PrevLB);
- Dir->setPrevUpperBoundVariable(Exprs.PrevUB);
- Dir->setDistInc(Exprs.DistInc);
- Dir->setPrevEnsureUpperBound(Exprs.PrevEUB);
Dir->setCounters(Exprs.Counters);
Dir->setPrivateCounters(Exprs.PrivateCounters);
Dir->setInits(Exprs.Inits);
diff --git a/lib/ASTMatchers/Dynamic/Registry.cpp b/lib/ASTMatchers/Dynamic/Registry.cpp
index 9fa693038194..6f935620888f 100644
--- a/lib/ASTMatchers/Dynamic/Registry.cpp
+++ b/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -296,6 +296,7 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(isCatchAll);
REGISTER_MATCHER(isClass);
REGISTER_MATCHER(isConst);
+ REGISTER_MATCHER(isConstexpr);
REGISTER_MATCHER(isConstQualified);
REGISTER_MATCHER(isCopyAssignmentOperator);
REGISTER_MATCHER(isCopyConstructor);
diff --git a/lib/Basic/Attributes.cpp b/lib/Basic/Attributes.cpp
index c215366fc398..b7570d03c85a 100644
--- a/lib/Basic/Attributes.cpp
+++ b/lib/Basic/Attributes.cpp
@@ -1,4 +1,5 @@
#include "clang/Basic/Attributes.h"
+#include "clang/Basic/AttrSubjectMatchRules.h"
#include "clang/Basic/IdentifierTable.h"
#include "llvm/ADT/StringSwitch.h"
using namespace clang;
@@ -15,3 +16,13 @@ int clang::hasAttribute(AttrSyntax Syntax, const IdentifierInfo *Scope,
return 0;
}
+
+const char *attr::getSubjectMatchRuleSpelling(attr::SubjectMatchRule Rule) {
+ switch (Rule) {
+#define ATTR_MATCH_RULE(NAME, SPELLING, IsAbstract) \
+ case attr::NAME: \
+ return SPELLING;
+#include "clang/Basic/AttrSubMatchRulesList.inc"
+ }
+ llvm_unreachable("Invalid subject match rule");
+}
diff --git a/lib/Basic/OpenMPKinds.cpp b/lib/Basic/OpenMPKinds.cpp
index 5a8bb61eaadf..76a0e18c2d73 100644
--- a/lib/Basic/OpenMPKinds.cpp
+++ b/lib/Basic/OpenMPKinds.cpp
@@ -854,14 +854,10 @@ bool clang::isOpenMPTaskingDirective(OpenMPDirectiveKind Kind) {
bool clang::isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind) {
return Kind == OMPD_distribute_parallel_for ||
Kind == OMPD_distribute_parallel_for_simd ||
- Kind == OMPD_distribute_simd || Kind == OMPD_teams_distribute ||
- Kind == OMPD_teams_distribute_simd ||
Kind == OMPD_teams_distribute_parallel_for_simd ||
Kind == OMPD_teams_distribute_parallel_for ||
- Kind == OMPD_target_teams_distribute ||
Kind == OMPD_target_teams_distribute_parallel_for ||
- Kind == OMPD_target_teams_distribute_parallel_for_simd ||
- Kind == OMPD_target_teams_distribute_simd;
+ Kind == OMPD_target_teams_distribute_parallel_for_simd;
}
void clang::getOpenMPCaptureRegions(
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index a457f6deee75..d7f1793e377c 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -5467,9 +5467,11 @@ public:
Builder.defineMacro("__arm__");
// For bare-metal none-eabi.
if (getTriple().getOS() == llvm::Triple::UnknownOS &&
- getTriple().getEnvironment() == llvm::Triple::EABI)
+ (getTriple().getEnvironment() == llvm::Triple::EABI ||
+ getTriple().getEnvironment() == llvm::Triple::EABIHF))
Builder.defineMacro("__ELF__");
+
// Target properties.
Builder.defineMacro("__REGISTER_PREFIX__", "");
@@ -6118,6 +6120,11 @@ public:
MacroBuilder &Builder) const override {
// Target identification.
Builder.defineMacro("__aarch64__");
+ // For bare-metal none-eabi.
+ if (getTriple().getOS() == llvm::Triple::UnknownOS &&
+ (getTriple().getEnvironment() == llvm::Triple::EABI ||
+ getTriple().getEnvironment() == llvm::Triple::EABIHF))
+ Builder.defineMacro("__ELF__");
// Target properties.
Builder.defineMacro("_LP64");
diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp
index 855d6795b9d6..20059d922f90 100644
--- a/lib/CodeGen/BackendUtil.cpp
+++ b/lib/CodeGen/BackendUtil.cpp
@@ -83,9 +83,6 @@ class EmitAssemblyHelper {
return TargetIRAnalysis();
}
- /// Set LLVM command line options passed through -backend-option.
- void setCommandLineOpts();
-
void CreatePasses(legacy::PassManager &MPM, legacy::FunctionPassManager &FPM);
/// Generates the TargetMachine.
@@ -372,7 +369,9 @@ static void initTargetOptions(llvm::TargetOptions &Options,
// Set FP fusion mode.
switch (LangOpts.getDefaultFPContractMode()) {
case LangOptions::FPC_Off:
- Options.AllowFPOpFusion = llvm::FPOpFusion::Strict;
+ // Preserve any contraction performed by the front-end. (Strict performs
+ // splitting of the muladd instrinsic in the backend.)
+ Options.AllowFPOpFusion = llvm::FPOpFusion::Standard;
break;
case LangOptions::FPC_On:
Options.AllowFPOpFusion = llvm::FPOpFusion::Standard;
@@ -604,7 +603,7 @@ void EmitAssemblyHelper::CreatePasses(legacy::PassManager &MPM,
PMBuilder.populateModulePassManager(MPM);
}
-void EmitAssemblyHelper::setCommandLineOpts() {
+static void setCommandLineOpts(const CodeGenOptions &CodeGenOpts) {
SmallVector<const char *, 16> BackendArgs;
BackendArgs.push_back("clang"); // Fake program name.
if (!CodeGenOpts.DebugPass.empty()) {
@@ -677,7 +676,7 @@ void EmitAssemblyHelper::EmitAssembly(BackendAction Action,
std::unique_ptr<raw_pwrite_stream> OS) {
TimeRegion Region(llvm::TimePassesIsEnabled ? &CodeGenerationTime : nullptr);
- setCommandLineOpts();
+ setCommandLineOpts(CodeGenOpts);
bool UsesCodeGen = (Action != Backend_EmitNothing &&
Action != Backend_EmitBC &&
@@ -806,7 +805,7 @@ static PassBuilder::OptimizationLevel mapToLevel(const CodeGenOptions &Opts) {
void EmitAssemblyHelper::EmitAssemblyWithNewPassManager(
BackendAction Action, std::unique_ptr<raw_pwrite_stream> OS) {
TimeRegion Region(llvm::TimePassesIsEnabled ? &CodeGenerationTime : nullptr);
- setCommandLineOpts();
+ setCommandLineOpts(CodeGenOpts);
// The new pass manager always makes a target machine available to passes
// during construction.
@@ -944,6 +943,8 @@ static void runThinLTOBackend(ModuleSummaryIndex *CombinedIndex, Module *M,
ModuleToDefinedGVSummaries;
CombinedIndex->collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
+ setCommandLineOpts(CGOpts);
+
// We can simply import the values mentioned in the combined index, since
// we should only invoke this using the individual indexes written out
// via a WriteIndexesThinBackend.
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index 8af32055fc4c..26235257b19d 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -1586,9 +1586,10 @@ CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI) {
case ABIArgInfo::Indirect: {
assert(NumIRArgs == 1);
- // indirect arguments are always on the stack, which is addr space #0.
+ // indirect arguments are always on the stack, which is alloca addr space.
llvm::Type *LTy = ConvertTypeForMem(it->type);
- ArgTypes[FirstIRArg] = LTy->getPointerTo();
+ ArgTypes[FirstIRArg] = LTy->getPointerTo(
+ CGM.getDataLayout().getAllocaAddrSpace());
break;
}
@@ -1761,7 +1762,7 @@ void CodeGenModule::AddDefaultFnAttrs(llvm::Function &F) {
void CodeGenModule::ConstructAttributeList(
StringRef Name, const CGFunctionInfo &FI, CGCalleeInfo CalleeInfo,
- AttributeListType &PAL, unsigned &CallingConv, bool AttrOnCallSite) {
+ llvm::AttributeList &AttrList, unsigned &CallingConv, bool AttrOnCallSite) {
llvm::AttrBuilder FuncAttrs;
llvm::AttrBuilder RetAttrs;
@@ -1930,13 +1931,8 @@ void CodeGenModule::ConstructAttributeList(
RetAttrs.addAttribute(llvm::Attribute::NonNull);
}
- // Attach return attributes.
- if (RetAttrs.hasAttributes()) {
- PAL.push_back(llvm::AttributeList::get(
- getLLVMContext(), llvm::AttributeList::ReturnIndex, RetAttrs));
- }
-
bool hasUsedSRet = false;
+ SmallVector<llvm::AttributeSet, 4> ArgAttrs(IRFunctionArgs.totalIRArgs());
// Attach attributes to sret.
if (IRFunctionArgs.hasSRetArg()) {
@@ -1945,16 +1941,16 @@ void CodeGenModule::ConstructAttributeList(
hasUsedSRet = true;
if (RetAI.getInReg())
SRETAttrs.addAttribute(llvm::Attribute::InReg);
- PAL.push_back(llvm::AttributeList::get(
- getLLVMContext(), IRFunctionArgs.getSRetArgNo() + 1, SRETAttrs));
+ ArgAttrs[IRFunctionArgs.getSRetArgNo()] =
+ llvm::AttributeSet::get(getLLVMContext(), SRETAttrs);
}
// Attach attributes to inalloca argument.
if (IRFunctionArgs.hasInallocaArg()) {
llvm::AttrBuilder Attrs;
Attrs.addAttribute(llvm::Attribute::InAlloca);
- PAL.push_back(llvm::AttributeList::get(
- getLLVMContext(), IRFunctionArgs.getInallocaArgNo() + 1, Attrs));
+ ArgAttrs[IRFunctionArgs.getInallocaArgNo()] =
+ llvm::AttributeSet::get(getLLVMContext(), Attrs);
}
unsigned ArgNo = 0;
@@ -1967,10 +1963,12 @@ void CodeGenModule::ConstructAttributeList(
// Add attribute for padding argument, if necessary.
if (IRFunctionArgs.hasPaddingArg(ArgNo)) {
- if (AI.getPaddingInReg())
- PAL.push_back(llvm::AttributeList::get(
- getLLVMContext(), IRFunctionArgs.getPaddingArgNo(ArgNo) + 1,
- llvm::Attribute::InReg));
+ if (AI.getPaddingInReg()) {
+ ArgAttrs[IRFunctionArgs.getPaddingArgNo(ArgNo)] =
+ llvm::AttributeSet::get(
+ getLLVMContext(),
+ llvm::AttrBuilder().addAttribute(llvm::Attribute::InReg));
+ }
}
// 'restrict' -> 'noalias' is done in EmitFunctionProlog when we
@@ -2085,15 +2083,15 @@ void CodeGenModule::ConstructAttributeList(
unsigned FirstIRArg, NumIRArgs;
std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
for (unsigned i = 0; i < NumIRArgs; i++)
- PAL.push_back(llvm::AttributeList::get(getLLVMContext(),
- FirstIRArg + i + 1, Attrs));
+ ArgAttrs[FirstIRArg + i] =
+ llvm::AttributeSet::get(getLLVMContext(), Attrs);
}
}
assert(ArgNo == FI.arg_size());
- if (FuncAttrs.hasAttributes())
- PAL.push_back(llvm::AttributeList::get(
- getLLVMContext(), llvm::AttributeList::FunctionIndex, FuncAttrs));
+ AttrList = llvm::AttributeList::get(
+ getLLVMContext(), llvm::AttributeSet::get(getLLVMContext(), FuncAttrs),
+ llvm::AttributeSet::get(getLLVMContext(), RetAttrs), ArgAttrs);
}
/// An argument came in as a promoted argument; demote it back to its
@@ -2204,8 +2202,7 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
if (IRFunctionArgs.hasSRetArg()) {
auto AI = cast<llvm::Argument>(FnArgs[IRFunctionArgs.getSRetArgNo()]);
AI->setName("agg.result");
- AI->addAttr(llvm::AttributeList::get(getLLVMContext(), AI->getArgNo() + 1,
- llvm::Attribute::NoAlias));
+ AI->addAttr(llvm::Attribute::NoAlias);
}
// Track if we received the parameter as a pointer (indirect, byval, or
@@ -2296,9 +2293,7 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
if (const ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(Arg)) {
if (getNonNullAttr(CurCodeDecl, PVD, PVD->getType(),
PVD->getFunctionScopeIndex()))
- AI->addAttr(llvm::AttributeList::get(getLLVMContext(),
- AI->getArgNo() + 1,
- llvm::Attribute::NonNull));
+ AI->addAttr(llvm::Attribute::NonNull);
QualType OTy = PVD->getOriginalType();
if (const auto *ArrTy =
@@ -2315,12 +2310,9 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
llvm::AttrBuilder Attrs;
Attrs.addDereferenceableAttr(
getContext().getTypeSizeInChars(ETy).getQuantity()*ArrSize);
- AI->addAttr(llvm::AttributeList::get(
- getLLVMContext(), AI->getArgNo() + 1, Attrs));
+ AI->addAttrs(Attrs);
} else if (getContext().getTargetAddressSpace(ETy) == 0) {
- AI->addAttr(llvm::AttributeList::get(getLLVMContext(),
- AI->getArgNo() + 1,
- llvm::Attribute::NonNull));
+ AI->addAttr(llvm::Attribute::NonNull);
}
}
} else if (const auto *ArrTy =
@@ -2330,34 +2322,26 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
// we know that it must be nonnull.
if (ArrTy->getSizeModifier() == VariableArrayType::Static &&
!getContext().getTargetAddressSpace(ArrTy->getElementType()))
- AI->addAttr(llvm::AttributeList::get(getLLVMContext(),
- AI->getArgNo() + 1,
- llvm::Attribute::NonNull));
+ AI->addAttr(llvm::Attribute::NonNull);
}
const auto *AVAttr = PVD->getAttr<AlignValueAttr>();
if (!AVAttr)
if (const auto *TOTy = dyn_cast<TypedefType>(OTy))
AVAttr = TOTy->getDecl()->getAttr<AlignValueAttr>();
- if (AVAttr) {
+ if (AVAttr) {
llvm::Value *AlignmentValue =
EmitScalarExpr(AVAttr->getAlignment());
llvm::ConstantInt *AlignmentCI =
cast<llvm::ConstantInt>(AlignmentValue);
- unsigned Alignment =
- std::min((unsigned) AlignmentCI->getZExtValue(),
- +llvm::Value::MaximumAlignment);
-
- llvm::AttrBuilder Attrs;
- Attrs.addAlignmentAttr(Alignment);
- AI->addAttr(llvm::AttributeList::get(getLLVMContext(),
- AI->getArgNo() + 1, Attrs));
+ unsigned Alignment = std::min((unsigned)AlignmentCI->getZExtValue(),
+ +llvm::Value::MaximumAlignment);
+ AI->addAttrs(llvm::AttrBuilder().addAlignmentAttr(Alignment));
}
}
if (Arg->getType().isRestrictQualified())
- AI->addAttr(llvm::AttributeList::get(
- getLLVMContext(), AI->getArgNo() + 1, llvm::Attribute::NoAlias));
+ AI->addAttr(llvm::Attribute::NoAlias);
// LLVM expects swifterror parameters to be used in very restricted
// ways. Copy the value into a less-restricted temporary.
@@ -4113,13 +4097,10 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
// Compute the calling convention and attributes.
unsigned CallingConv;
- CodeGen::AttributeListType AttributeList;
+ llvm::AttributeList Attrs;
CGM.ConstructAttributeList(CalleePtr->getName(), CallInfo,
- Callee.getAbstractInfo(),
- AttributeList, CallingConv,
+ Callee.getAbstractInfo(), Attrs, CallingConv,
/*AttrOnCallSite=*/true);
- llvm::AttributeList Attrs =
- llvm::AttributeList::get(getLLVMContext(), AttributeList);
// Apply some call-site-specific attributes.
// TODO: work this into building the attribute set.
diff --git a/lib/CodeGen/CGCall.h b/lib/CodeGen/CGCall.h
index 97221e20c195..7e10407fc31c 100644
--- a/lib/CodeGen/CGCall.h
+++ b/lib/CodeGen/CGCall.h
@@ -39,7 +39,6 @@ namespace clang {
class VarDecl;
namespace CodeGen {
-typedef SmallVector<llvm::AttributeList, 8> AttributeListType;
/// Abstract information about a function or function prototype.
class CGCalleeInfo {
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 818b51543d30..2f6a2b95fb61 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -3466,17 +3466,17 @@ void CGDebugInfo::EmitDeclare(const VarDecl *VD, llvm::Value *Storage,
// functions there won't be an implicit param at arg1 and
// otherwise it is 'self' or 'this'.
if (isa<ImplicitParamDecl>(VD) && ArgNo && *ArgNo == 1)
- Flags |= llvm::DINode::FlagObjectPointer;
- if (auto *Arg = dyn_cast<llvm::Argument>(Storage))
- if (Arg->getType()->isPointerTy() && !Arg->hasByValAttr() &&
- !VD->getType()->isPointerType())
- Expr.push_back(llvm::dwarf::DW_OP_deref);
+ Flags |= llvm::DINode::FlagObjectPointer;
+ // Note: Older versions of clang used to emit byval references with an extra
+ // DW_OP_deref, because they referenced the IR arg directly instead of
+ // referencing an alloca. Newer versions of LLVM don't treat allocas
+ // differently from other function arguments when used in a dbg.declare.
auto *Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
-
StringRef Name = VD->getName();
if (!Name.empty()) {
if (VD->hasAttr<BlocksAttr>()) {
+ // Here, we need an offset *into* the alloca.
CharUnits offset = CharUnits::fromQuantity(32);
Expr.push_back(llvm::dwarf::DW_OP_plus);
// offset of __forwarding field
@@ -3488,22 +3488,7 @@ void CGDebugInfo::EmitDeclare(const VarDecl *VD, llvm::Value *Storage,
// offset of x field
offset = CGM.getContext().toCharUnitsFromBits(XOffset);
Expr.push_back(offset.getQuantity());
-
- // Create the descriptor for the variable.
- auto *D = ArgNo
- ? DBuilder.createParameterVariable(Scope, VD->getName(),
- *ArgNo, Unit, Line, Ty)
- : DBuilder.createAutoVariable(Scope, VD->getName(), Unit,
- Line, Ty, Align);
-
- // Insert an llvm.dbg.declare into the current block.
- DBuilder.insertDeclare(
- Storage, D, DBuilder.createExpression(Expr),
- llvm::DebugLoc::get(Line, Column, Scope, CurInlinedAt),
- Builder.GetInsertBlock());
- return;
- } else if (isa<VariableArrayType>(VD->getType()))
- Expr.push_back(llvm::dwarf::DW_OP_deref);
+ }
} else if (const auto *RT = dyn_cast<RecordType>(VD->getType())) {
// If VD is an anonymous union then Storage represents value for
// all union fields.
@@ -3606,8 +3591,7 @@ void CGDebugInfo::EmitDeclareOfBlockDeclRefVariable(
->getElementOffset(blockInfo.getCapture(VD).getIndex()));
SmallVector<int64_t, 9> addr;
- if (isa<llvm::AllocaInst>(Storage))
- addr.push_back(llvm::dwarf::DW_OP_deref);
+ addr.push_back(llvm::dwarf::DW_OP_deref);
addr.push_back(llvm::dwarf::DW_OP_plus);
addr.push_back(offset.getQuantity());
if (isByRef) {
@@ -3633,12 +3617,11 @@ void CGDebugInfo::EmitDeclareOfBlockDeclRefVariable(
// Insert an llvm.dbg.declare into the current block.
auto DL =
llvm::DebugLoc::get(Line, Column, LexicalBlockStack.back(), CurInlinedAt);
+ auto *Expr = DBuilder.createExpression(addr);
if (InsertPoint)
- DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(addr), DL,
- InsertPoint);
+ DBuilder.insertDeclare(Storage, D, Expr, DL, InsertPoint);
else
- DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(addr), DL,
- Builder.GetInsertBlock());
+ DBuilder.insertDeclare(Storage, D, Expr, DL, Builder.GetInsertBlock());
}
void CGDebugInfo::EmitDeclareOfArgVariable(const VarDecl *VD, llvm::Value *AI,
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index 0f959043a22e..10a0b46d9028 100644
--- a/lib/CodeGen/CGDecl.cpp
+++ b/lib/CodeGen/CGDecl.cpp
@@ -924,7 +924,7 @@ llvm::Value *CodeGenFunction::EmitLifetimeStart(uint64_t Size,
return nullptr;
llvm::Value *SizeV = llvm::ConstantInt::get(Int64Ty, Size);
- Addr = Builder.CreateBitCast(Addr, Int8PtrTy);
+ Addr = Builder.CreateBitCast(Addr, AllocaInt8PtrTy);
llvm::CallInst *C =
Builder.CreateCall(CGM.getLLVMLifetimeStartFn(), {SizeV, Addr});
C->setDoesNotThrow();
@@ -932,7 +932,7 @@ llvm::Value *CodeGenFunction::EmitLifetimeStart(uint64_t Size,
}
void CodeGenFunction::EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr) {
- Addr = Builder.CreateBitCast(Addr, Int8PtrTy);
+ Addr = Builder.CreateBitCast(Addr, AllocaInt8PtrTy);
llvm::CallInst *C =
Builder.CreateCall(CGM.getLLVMLifetimeEndFn(), {Size, Addr});
C->setDoesNotThrow();
@@ -1728,7 +1728,7 @@ llvm::Constant *CodeGenModule::getLLVMLifetimeStartFn() {
if (LifetimeStartFn)
return LifetimeStartFn;
LifetimeStartFn = llvm::Intrinsic::getDeclaration(&getModule(),
- llvm::Intrinsic::lifetime_start, Int8PtrTy);
+ llvm::Intrinsic::lifetime_start, AllocaInt8PtrTy);
return LifetimeStartFn;
}
@@ -1737,7 +1737,7 @@ llvm::Constant *CodeGenModule::getLLVMLifetimeEndFn() {
if (LifetimeEndFn)
return LifetimeEndFn;
LifetimeEndFn = llvm::Intrinsic::getDeclaration(&getModule(),
- llvm::Intrinsic::lifetime_end, Int8PtrTy);
+ llvm::Intrinsic::lifetime_end, AllocaInt8PtrTy);
return LifetimeEndFn;
}
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index 265ef27a46b0..719147a58e08 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -533,6 +533,15 @@ bool CodeGenFunction::sanitizePerformTypeCheck() const {
SanOpts.has(SanitizerKind::Vptr);
}
+/// Check if a runtime null check for \p Ptr can be omitted.
+static bool canOmitPointerNullCheck(llvm::Value *Ptr) {
+ // Note: do not perform any constant-folding in this function. That is best
+ // left to the IR builder.
+
+ // Pointers to alloca'd memory are non-null.
+ return isa<llvm::AllocaInst>(Ptr->stripPointerCastsNoFollowAliases());
+}
+
void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
llvm::Value *Ptr, QualType Ty,
CharUnits Alignment,
@@ -554,19 +563,28 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
bool AllowNullPointers = TCK == TCK_DowncastPointer || TCK == TCK_Upcast ||
TCK == TCK_UpcastToVirtualBase;
if ((SanOpts.has(SanitizerKind::Null) || AllowNullPointers) &&
- !SkippedChecks.has(SanitizerKind::Null)) {
+ !SkippedChecks.has(SanitizerKind::Null) &&
+ !canOmitPointerNullCheck(Ptr)) {
// The glvalue must not be an empty glvalue.
llvm::Value *IsNonNull = Builder.CreateIsNotNull(Ptr);
- if (AllowNullPointers) {
- // When performing pointer casts, it's OK if the value is null.
- // Skip the remaining checks in that case.
- Done = createBasicBlock("null");
- llvm::BasicBlock *Rest = createBasicBlock("not.null");
- Builder.CreateCondBr(IsNonNull, Rest, Done);
- EmitBlock(Rest);
- } else {
- Checks.push_back(std::make_pair(IsNonNull, SanitizerKind::Null));
+ // The IR builder can constant-fold the null check if the pointer points to
+ // a constant.
+ bool PtrIsNonNull =
+ IsNonNull == llvm::ConstantInt::getTrue(getLLVMContext());
+
+ // Skip the null check if the pointer is known to be non-null.
+ if (!PtrIsNonNull) {
+ if (AllowNullPointers) {
+ // When performing pointer casts, it's OK if the value is null.
+ // Skip the remaining checks in that case.
+ Done = createBasicBlock("null");
+ llvm::BasicBlock *Rest = createBasicBlock("not.null");
+ Builder.CreateCondBr(IsNonNull, Rest, Done);
+ EmitBlock(Rest);
+ } else {
+ Checks.push_back(std::make_pair(IsNonNull, SanitizerKind::Null));
+ }
}
}
diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp
index 3db15c646f43..53c184130709 100644
--- a/lib/CodeGen/CGExprConstant.cpp
+++ b/lib/CodeGen/CGExprConstant.cpp
@@ -201,7 +201,7 @@ void ConstStructBuilder::AppendBitField(const FieldDecl *Field,
unsigned NewFieldWidth = FieldSize - BitsInPreviousByte;
if (CGM.getDataLayout().isBigEndian()) {
- Tmp = Tmp.lshr(NewFieldWidth);
+ Tmp.lshrInPlace(NewFieldWidth);
Tmp = Tmp.trunc(BitsInPreviousByte);
// We want the remaining high bits.
@@ -210,7 +210,7 @@ void ConstStructBuilder::AppendBitField(const FieldDecl *Field,
Tmp = Tmp.trunc(BitsInPreviousByte);
// We want the remaining low bits.
- FieldValue = FieldValue.lshr(BitsInPreviousByte);
+ FieldValue.lshrInPlace(BitsInPreviousByte);
FieldValue = FieldValue.trunc(NewFieldWidth);
}
}
@@ -273,7 +273,7 @@ void ConstStructBuilder::AppendBitField(const FieldDecl *Field,
// We want the low bits.
Tmp = FieldValue.trunc(CharWidth);
- FieldValue = FieldValue.lshr(CharWidth);
+ FieldValue.lshrInPlace(CharWidth);
}
Elements.push_back(llvm::ConstantInt::get(CGM.getLLVMContext(), Tmp));
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp
index 3a09a15dbc15..76e7df861f74 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/lib/CodeGen/CGObjC.cpp
@@ -126,10 +126,12 @@ llvm::Value *CodeGenFunction::EmitObjCCollectionLiteral(const Expr *E,
QualType IdTy(CGM.getContext().getObjCIdType());
llvm::Constant *Constant =
CGM.CreateRuntimeVariable(ConvertType(IdTy), ConstantName);
- Address Addr(Constant, Context.getTypeAlignInChars(IdTy));
- LValue LV = MakeAddrLValue(Addr, IdTy);
- return Builder.CreateBitCast(EmitLoadOfScalar(LV, E->getLocStart()),
- ConvertType(E->getType()));
+ LValue LV = MakeNaturalAlignAddrLValue(Constant, IdTy);
+ llvm::Value *Ptr = EmitLoadOfScalar(LV, E->getLocStart());
+ cast<llvm::LoadInst>(Ptr)->setMetadata(
+ CGM.getModule().getMDKindID("invariant.load"),
+ llvm::MDNode::get(getLLVMContext(), None));
+ return Builder.CreateBitCast(Ptr, ConvertType(E->getType()));
}
// Compute the type of the array we're initializing.
@@ -1848,12 +1850,8 @@ static llvm::Constant *createARCRuntimeFunction(CodeGenModule &CGM,
F->addFnAttr(llvm::Attribute::NonLazyBind);
}
- if (IsForwarding(Name)) {
- llvm::AttrBuilder B;
- B.addAttribute(llvm::Attribute::Returned);
-
- F->arg_begin()->addAttr(llvm::AttributeList::get(F->getContext(), 1, B));
- }
+ if (IsForwarding(Name))
+ F->arg_begin()->addAttr(llvm::Attribute::Returned);
}
return RTF;
diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp
index 0ebfd99363c1..683f366ebe45 100644
--- a/lib/CodeGen/CGStmt.cpp
+++ b/lib/CodeGen/CGStmt.cpp
@@ -1166,7 +1166,7 @@ void CodeGenFunction::EmitCaseStmtRange(const CaseStmt &S) {
if (Rem)
Rem--;
SwitchInsn->addCase(Builder.getInt(LHS), CaseDest);
- LHS++;
+ ++LHS;
}
return;
}
diff --git a/lib/CodeGen/CGVTables.cpp b/lib/CodeGen/CGVTables.cpp
index 7b0c8bf7d6e9..1869c0e809df 100644
--- a/lib/CodeGen/CGVTables.cpp
+++ b/lib/CodeGen/CGVTables.cpp
@@ -379,12 +379,9 @@ void CodeGenFunction::EmitMustTailThunk(const CXXMethodDecl *MD,
// Apply the standard set of call attributes.
unsigned CallingConv;
- CodeGen::AttributeListType AttributeList;
- CGM.ConstructAttributeList(CalleePtr->getName(),
- *CurFnInfo, MD, AttributeList,
+ llvm::AttributeList Attrs;
+ CGM.ConstructAttributeList(CalleePtr->getName(), *CurFnInfo, MD, Attrs,
CallingConv, /*AttrOnCallSite=*/true);
- llvm::AttributeList Attrs =
- llvm::AttributeList::get(getLLVMContext(), AttributeList);
Call->setAttributes(Attrs);
Call->setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index d48bff9c30a3..19203973ff1b 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -111,6 +111,8 @@ CodeGenModule::CodeGenModule(ASTContext &C, const HeaderSearchOptions &HSO,
C.getTargetInfo().getMaxPointerWidth());
Int8PtrTy = Int8Ty->getPointerTo(0);
Int8PtrPtrTy = Int8PtrTy->getPointerTo(0);
+ AllocaInt8PtrTy = Int8Ty->getPointerTo(
+ M.getDataLayout().getAllocaAddrSpace());
RuntimeCC = getTargetCodeGenInfo().getABIInfo().getRuntimeCC();
BuiltinCC = getTargetCodeGenInfo().getABIInfo().getBuiltinCC();
@@ -839,10 +841,9 @@ void CodeGenModule::SetLLVMFunctionAttributes(const Decl *D,
const CGFunctionInfo &Info,
llvm::Function *F) {
unsigned CallingConv;
- AttributeListType AttributeList;
- ConstructAttributeList(F->getName(), Info, D, AttributeList, CallingConv,
- false);
- F->setAttributes(llvm::AttributeList::get(getLLVMContext(), AttributeList));
+ llvm::AttributeList PAL;
+ ConstructAttributeList(F->getName(), Info, D, PAL, CallingConv, false);
+ F->setAttributes(PAL);
F->setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));
}
@@ -3793,6 +3794,10 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
AddDeferredUnusedCoverageMapping(D);
break;
+ case Decl::CXXDeductionGuide:
+ // Function-like, but does not result in code emission.
+ break;
+
case Decl::Var:
case Decl::Decomposition:
// Skip variable templates
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index d0b2dd717c8c..c4985ba41db1 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -1020,11 +1020,12 @@ public:
/// \param CalleeInfo - The callee information these attributes are being
/// constructed for. If valid, the attributes applied to this decl may
/// contribute to the function attributes and calling convention.
- /// \param PAL [out] - On return, the attribute list to use.
+ /// \param Attrs [out] - On return, the attribute list to use.
/// \param CallingConv [out] - On return, the LLVM calling convention to use.
void ConstructAttributeList(StringRef Name, const CGFunctionInfo &Info,
- CGCalleeInfo CalleeInfo, AttributeListType &PAL,
- unsigned &CallingConv, bool AttrOnCallSite);
+ CGCalleeInfo CalleeInfo,
+ llvm::AttributeList &Attrs, unsigned &CallingConv,
+ bool AttrOnCallSite);
/// Adds attributes to F according to our CodeGenOptions and LangOptions, as
/// though we had emitted it ourselves. We remove any attributes on F that
diff --git a/lib/CodeGen/CodeGenTypeCache.h b/lib/CodeGen/CodeGenTypeCache.h
index 47e26bcaa1b6..8ce9860cc638 100644
--- a/lib/CodeGen/CodeGenTypeCache.h
+++ b/lib/CodeGen/CodeGenTypeCache.h
@@ -60,6 +60,12 @@ struct CodeGenTypeCache {
llvm::PointerType *Int8PtrPtrTy;
};
+ /// void* in alloca address space
+ union {
+ llvm::PointerType *AllocaVoidPtrTy;
+ llvm::PointerType *AllocaInt8PtrTy;
+ };
+
/// The size and alignment of the builtin C type 'int'. This comes
/// up enough in various ABI lowering tasks to be worth pre-computing.
union {
diff --git a/lib/CodeGen/ModuleBuilder.cpp b/lib/CodeGen/ModuleBuilder.cpp
index 89090c8b6a1b..fc642850d60a 100644
--- a/lib/CodeGen/ModuleBuilder.cpp
+++ b/lib/CodeGen/ModuleBuilder.cpp
@@ -197,7 +197,7 @@ namespace {
// Provide some coverage mapping even for methods that aren't emitted.
// Don't do this for templated classes though, as they may not be
// instantiable.
- if (!MD->getParent()->getDescribedClassTemplate())
+ if (!MD->getParent()->isDependentContext())
Builder->AddDeferredUnusedCoverageMapping(MD);
}
diff --git a/lib/Driver/SanitizerArgs.cpp b/lib/Driver/SanitizerArgs.cpp
index b05596a99f6e..8e61aadbf326 100644
--- a/lib/Driver/SanitizerArgs.cpp
+++ b/lib/Driver/SanitizerArgs.cpp
@@ -469,34 +469,12 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
int LegacySanitizeCoverage;
if (Arg->getNumValues() == 1 &&
!StringRef(Arg->getValue(0))
- .getAsInteger(0, LegacySanitizeCoverage) &&
- LegacySanitizeCoverage >= 0 && LegacySanitizeCoverage <= 4) {
- switch (LegacySanitizeCoverage) {
- case 0:
- CoverageFeatures = 0;
- Arg->claim();
- break;
- case 1:
- D.Diag(diag::warn_drv_deprecated_arg) << Arg->getAsString(Args)
- << "-fsanitize-coverage=func";
- CoverageFeatures = CoverageFunc;
- break;
- case 2:
- D.Diag(diag::warn_drv_deprecated_arg) << Arg->getAsString(Args)
- << "-fsanitize-coverage=bb";
- CoverageFeatures = CoverageBB;
- break;
- case 3:
- D.Diag(diag::warn_drv_deprecated_arg) << Arg->getAsString(Args)
- << "-fsanitize-coverage=edge";
- CoverageFeatures = CoverageEdge;
- break;
- case 4:
+ .getAsInteger(0, LegacySanitizeCoverage)) {
+ CoverageFeatures = 0;
+ Arg->claim();
+ if (LegacySanitizeCoverage != 0) {
D.Diag(diag::warn_drv_deprecated_arg)
- << Arg->getAsString(Args)
- << "-fsanitize-coverage=edge,indirect-calls";
- CoverageFeatures = CoverageEdge | CoverageIndirCall;
- break;
+ << Arg->getAsString(Args) << "-fsanitize-coverage=trace-pc-guard";
}
continue;
}
@@ -530,16 +508,14 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
// Basic block tracing and 8-bit counters require some type of coverage
// enabled.
int CoverageTypes = CoverageFunc | CoverageBB | CoverageEdge;
- if ((CoverageFeatures & CoverageTraceBB) &&
- !(CoverageFeatures & CoverageTypes))
- D.Diag(clang::diag::err_drv_argument_only_allowed_with)
+ if (CoverageFeatures & CoverageTraceBB)
+ D.Diag(clang::diag::warn_drv_deprecated_arg)
<< "-fsanitize-coverage=trace-bb"
- << "-fsanitize-coverage=(func|bb|edge)";
- if ((CoverageFeatures & Coverage8bitCounters) &&
- !(CoverageFeatures & CoverageTypes))
- D.Diag(clang::diag::err_drv_argument_only_allowed_with)
+ << "-fsanitize-coverage=trace-pc-guard";
+ if (CoverageFeatures & Coverage8bitCounters)
+ D.Diag(clang::diag::warn_drv_deprecated_arg)
<< "-fsanitize-coverage=8bit-counters"
- << "-fsanitize-coverage=(func|bb|edge)";
+ << "-fsanitize-coverage=trace-pc-guard";
// trace-pc w/o func/bb/edge implies edge.
if ((CoverageFeatures & (CoverageTracePC | CoverageTracePCGuard)) &&
!(CoverageFeatures & CoverageTypes))
diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp
index f8eeeb4eef69..49708e7d7242 100644
--- a/lib/Driver/ToolChains/Clang.cpp
+++ b/lib/Driver/ToolChains/Clang.cpp
@@ -649,8 +649,24 @@ static void addDashXForInput(const ArgList &Args, const InputInfo &Input,
CmdArgs.push_back("-x");
if (Args.hasArg(options::OPT_rewrite_objc))
CmdArgs.push_back(types::getTypeName(types::TY_PP_ObjCXX));
- else
- CmdArgs.push_back(types::getTypeName(Input.getType()));
+ else {
+ // Map the driver type to the frontend type. This is mostly an identity
+ // mapping, except that the distinction between module interface units
+ // and other source files does not exist at the frontend layer.
+ const char *ClangType;
+ switch (Input.getType()) {
+ case types::TY_CXXModule:
+ ClangType = "c++";
+ break;
+ case types::TY_PP_CXXModule:
+ ClangType = "c++-cpp-output";
+ break;
+ default:
+ ClangType = types::getTypeName(Input.getType());
+ break;
+ }
+ CmdArgs.push_back(ClangType);
+ }
}
static void appendUserToPath(SmallVectorImpl<char> &Result) {
@@ -2290,6 +2306,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (!Args.hasFlag(options::OPT_fstrict_return, options::OPT_fno_strict_return,
true))
CmdArgs.push_back("-fno-strict-return");
+ if (Args.hasFlag(options::OPT_fallow_editor_placeholders,
+ options::OPT_fno_allow_editor_placeholders, false))
+ CmdArgs.push_back("-fallow-editor-placeholders");
if (Args.hasFlag(options::OPT_fstrict_vtable_pointers,
options::OPT_fno_strict_vtable_pointers,
false))
@@ -4996,6 +5015,19 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
case llvm::Triple::x86_64:
AddX86TargetArgs(Args, CmdArgs);
break;
+
+ case llvm::Triple::arm:
+ case llvm::Triple::armeb:
+ case llvm::Triple::thumb:
+ case llvm::Triple::thumbeb:
+ // This isn't in AddARMTargetArgs because we want to do this for assembly
+ // only, not C/C++.
+ if (Args.hasFlag(options::OPT_mdefault_build_attributes,
+ options::OPT_mno_default_build_attributes, true)) {
+ CmdArgs.push_back("-mllvm");
+ CmdArgs.push_back("-arm-add-build-attributes");
+ }
+ break;
}
// Consume all the warning flags. Usually this would be handled more
diff --git a/lib/Driver/ToolChains/CommonArgs.cpp b/lib/Driver/ToolChains/CommonArgs.cpp
index e5f4a3b8d605..93b66eb6954a 100644
--- a/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/lib/Driver/ToolChains/CommonArgs.cpp
@@ -261,6 +261,12 @@ std::string tools::getCPUName(const ArgList &Args, const llvm::Triple &T,
arm::getARMArchCPUFromArgs(Args, MArch, MCPU, FromAs);
return arm::getARMTargetCPU(MCPU, MArch, T);
}
+
+ case llvm::Triple::avr:
+ if (const Arg *A = Args.getLastArg(options::OPT_mmcu_EQ))
+ return A->getValue();
+ return "";
+
case llvm::Triple::mips:
case llvm::Triple::mipsel:
case llvm::Triple::mips64:
@@ -426,11 +432,12 @@ void tools::addArchSpecificRPath(const ToolChain &TC, const ArgList &Args,
}
}
-void tools::addOpenMPRuntime(ArgStringList &CmdArgs, const ToolChain &TC,
- const ArgList &Args) {
+bool tools::addOpenMPRuntime(ArgStringList &CmdArgs, const ToolChain &TC,
+ const ArgList &Args, bool IsOffloadingHost,
+ bool GompNeedsRT) {
if (!Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
options::OPT_fno_openmp, false))
- return;
+ return false;
switch (TC.getDriver().getOpenMPRuntime(Args)) {
case Driver::OMPRT_OMP:
@@ -438,16 +445,24 @@ void tools::addOpenMPRuntime(ArgStringList &CmdArgs, const ToolChain &TC,
break;
case Driver::OMPRT_GOMP:
CmdArgs.push_back("-lgomp");
+
+ if (GompNeedsRT)
+ CmdArgs.push_back("-lrt");
break;
case Driver::OMPRT_IOMP5:
CmdArgs.push_back("-liomp5");
break;
case Driver::OMPRT_Unknown:
// Already diagnosed.
- break;
+ return false;
}
+ if (IsOffloadingHost)
+ CmdArgs.push_back("-lomptarget");
+
addArchSpecificRPath(TC, Args, CmdArgs);
+
+ return true;
}
static void addSanitizerRuntime(const ToolChain &TC, const ArgList &Args,
diff --git a/lib/Driver/ToolChains/CommonArgs.h b/lib/Driver/ToolChains/CommonArgs.h
index f5747aa85f22..fdeb6669b0a8 100644
--- a/lib/Driver/ToolChains/CommonArgs.h
+++ b/lib/Driver/ToolChains/CommonArgs.h
@@ -59,8 +59,10 @@ void AddAssemblerKPIC(const ToolChain &ToolChain,
void addArchSpecificRPath(const ToolChain &TC, const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs);
-void addOpenMPRuntime(llvm::opt::ArgStringList &CmdArgs, const ToolChain &TC,
- const llvm::opt::ArgList &Args);
+/// Returns true, if an OpenMP runtime has been added.
+bool addOpenMPRuntime(llvm::opt::ArgStringList &CmdArgs, const ToolChain &TC,
+ const llvm::opt::ArgList &Args,
+ bool IsOffloadingHost = false, bool GompNeedsRT = false);
llvm::opt::Arg *getLastProfileUseArg(const llvm::opt::ArgList &Args);
llvm::opt::Arg *getLastProfileSampleUseArg(const llvm::opt::ArgList &Args);
diff --git a/lib/Driver/ToolChains/Gnu.cpp b/lib/Driver/ToolChains/Gnu.cpp
index 549e24cbd2b3..313bf38c2860 100644
--- a/lib/Driver/ToolChains/Gnu.cpp
+++ b/lib/Driver/ToolChains/Gnu.cpp
@@ -586,37 +586,15 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
bool WantPthread = Args.hasArg(options::OPT_pthread) ||
Args.hasArg(options::OPT_pthreads);
- if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
- options::OPT_fno_openmp, false)) {
+ // FIXME: Only pass GompNeedsRT = true for platforms with libgomp that
+ // require librt. Most modern Linux platforms do, but some may not.
+ if (addOpenMPRuntime(CmdArgs, ToolChain, Args,
+ JA.isHostOffloading(Action::OFK_OpenMP),
+ /* GompNeedsRT= */ true))
// OpenMP runtimes implies pthreads when using the GNU toolchain.
// FIXME: Does this really make sense for all GNU toolchains?
WantPthread = true;
- // Also link the particular OpenMP runtimes.
- switch (ToolChain.getDriver().getOpenMPRuntime(Args)) {
- case Driver::OMPRT_OMP:
- CmdArgs.push_back("-lomp");
- break;
- case Driver::OMPRT_GOMP:
- CmdArgs.push_back("-lgomp");
-
- // FIXME: Exclude this for platforms with libgomp that don't require
- // librt. Most modern Linux platforms require it, but some may not.
- CmdArgs.push_back("-lrt");
- break;
- case Driver::OMPRT_IOMP5:
- CmdArgs.push_back("-liomp5");
- break;
- case Driver::OMPRT_Unknown:
- // Already diagnosed.
- break;
- }
- if (JA.isHostOffloading(Action::OFK_OpenMP))
- CmdArgs.push_back("-lomptarget");
-
- addArchSpecificRPath(ToolChain, Args, CmdArgs);
- }
-
AddRunTimeLibs(ToolChain, D, CmdArgs, Args);
if (WantPthread && !isAndroid)
@@ -770,6 +748,12 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C,
Args.AddLastArg(CmdArgs, options::OPT_mfpu_EQ);
break;
}
+ case llvm::Triple::aarch64:
+ case llvm::Triple::aarch64_be: {
+ Args.AddLastArg(CmdArgs, options::OPT_march_EQ);
+ Args.AddLastArg(CmdArgs, options::OPT_mcpu_EQ);
+ break;
+ }
case llvm::Triple::mips:
case llvm::Triple::mipsel:
case llvm::Triple::mips64:
diff --git a/lib/Driver/ToolChains/MinGW.cpp b/lib/Driver/ToolChains/MinGW.cpp
index ca5bf06f7e7d..7550bab486f1 100644
--- a/lib/Driver/ToolChains/MinGW.cpp
+++ b/lib/Driver/ToolChains/MinGW.cpp
@@ -285,28 +285,30 @@ void toolchains::MinGW::findGccLibDir() {
}
}
+llvm::ErrorOr<std::string> toolchains::MinGW::findGcc() {
+ llvm::SmallVector<llvm::SmallString<32>, 2> Gccs;
+ Gccs.emplace_back(getTriple().getArchName());
+ Gccs[0] += "-w64-mingw32-gcc";
+ Gccs.emplace_back("mingw32-gcc");
+ // Please do not add "gcc" here
+ for (StringRef CandidateGcc : Gccs)
+ if (llvm::ErrorOr<std::string> GPPName = llvm::sys::findProgramByName(CandidateGcc))
+ return GPPName;
+ return make_error_code(std::errc::no_such_file_or_directory);
+}
+
toolchains::MinGW::MinGW(const Driver &D, const llvm::Triple &Triple,
const ArgList &Args)
: ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args) {
getProgramPaths().push_back(getDriver().getInstalledDir());
-// In Windows there aren't any standard install locations, we search
-// for gcc on the PATH. In Linux the base is always /usr.
-#ifdef LLVM_ON_WIN32
if (getDriver().SysRoot.size())
Base = getDriver().SysRoot;
- else if (llvm::ErrorOr<std::string> GPPName =
- llvm::sys::findProgramByName("gcc"))
+ else if (llvm::ErrorOr<std::string> GPPName = findGcc())
Base = llvm::sys::path::parent_path(
llvm::sys::path::parent_path(GPPName.get()));
else
Base = llvm::sys::path::parent_path(getDriver().getInstalledDir());
-#else
- if (getDriver().SysRoot.size())
- Base = getDriver().SysRoot;
- else
- Base = "/usr";
-#endif
Base += llvm::sys::path::get_separator();
findGccLibDir();
diff --git a/lib/Driver/ToolChains/MinGW.h b/lib/Driver/ToolChains/MinGW.h
index 9d2468ffa234..cf1628a4ccdd 100644
--- a/lib/Driver/ToolChains/MinGW.h
+++ b/lib/Driver/ToolChains/MinGW.h
@@ -93,6 +93,7 @@ private:
mutable std::unique_ptr<tools::gcc::Preprocessor> Preprocessor;
mutable std::unique_ptr<tools::gcc::Compiler> Compiler;
void findGccLibDir();
+ llvm::ErrorOr<std::string> findGcc();
};
} // end namespace toolchains
diff --git a/lib/Format/FormatTokenLexer.cpp b/lib/Format/FormatTokenLexer.cpp
index 4ee43d6937e0..1acc0c306512 100644
--- a/lib/Format/FormatTokenLexer.cpp
+++ b/lib/Format/FormatTokenLexer.cpp
@@ -467,6 +467,9 @@ FormatToken *FormatTokenLexer::getNextToken() {
if (pos >= 0 && Text[pos] == '\r')
--pos;
// See whether there is an odd number of '\' before this.
+ // FIXME: This is wrong. A '\' followed by a newline is always removed,
+ // regardless of whether there is another '\' before it.
+ // FIXME: Newlines can also be escaped by a '?' '?' '/' trigraph.
unsigned count = 0;
for (; pos >= 0; --pos, ++count)
if (Text[pos] != '\\')
diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp
index 004800fc2a4e..bbc2d1e52b63 100644
--- a/lib/Format/TokenAnnotator.cpp
+++ b/lib/Format/TokenAnnotator.cpp
@@ -796,10 +796,11 @@ private:
while (CurrentToken) {
FormatToken *Tok = CurrentToken;
next();
- if (Tok->isOneOf(Keywords.kw___has_include,
- Keywords.kw___has_include_next)) {
+ if (Tok->is(tok::l_paren))
+ parseParens();
+ else if (Tok->isOneOf(Keywords.kw___has_include,
+ Keywords.kw___has_include_next))
parseHasInclude();
- }
}
return Type;
}
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index ab9f20304c9c..0e0eb40eb334 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -1353,13 +1353,11 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
.Case("cl", IK_OpenCL)
.Case("cuda", IK_CUDA)
.Case("c++", IK_CXX)
- .Case("c++-module", IK_CXX)
.Case("objective-c", IK_ObjC)
.Case("objective-c++", IK_ObjCXX)
.Case("cpp-output", IK_PreprocessedC)
.Case("assembler-with-cpp", IK_Asm)
.Case("c++-cpp-output", IK_PreprocessedCXX)
- .Case("c++-module-cpp-output", IK_PreprocessedCXX)
.Case("cuda-cpp-output", IK_PreprocessedCuda)
.Case("objective-c-cpp-output", IK_PreprocessedObjC)
.Case("objc-cpp-output", IK_PreprocessedObjC)
@@ -2324,6 +2322,9 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
Args.getAllArgValues(OPT_fxray_always_instrument);
Opts.XRayNeverInstrumentFiles =
Args.getAllArgValues(OPT_fxray_never_instrument);
+
+ // -fallow-editor-placeholders
+ Opts.AllowEditorPlaceholders = Args.hasArg(OPT_fallow_editor_placeholders);
}
static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
diff --git a/lib/Headers/smmintrin.h b/lib/Headers/smmintrin.h
index dccba4e40b2d..1c94aca69381 100644
--- a/lib/Headers/smmintrin.h
+++ b/lib/Headers/smmintrin.h
@@ -56,8 +56,7 @@
/// __m128 _mm_ceil_ps(__m128 X);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VROUNDPS / ROUNDPS </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VROUNDPS / ROUNDPS </c> instruction.
///
/// \param X
/// A 128-bit vector of [4 x float] values to be rounded up.
@@ -74,8 +73,7 @@
/// __m128d _mm_ceil_pd(__m128d X);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VROUNDPD / ROUNDPD </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VROUNDPD / ROUNDPD </c> instruction.
///
/// \param X
/// A 128-bit vector of [2 x double] values to be rounded up.
@@ -94,8 +92,7 @@
/// __m128 _mm_ceil_ss(__m128 X, __m128 Y);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VROUNDSS / ROUNDSS </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VROUNDSS / ROUNDSS </c> instruction.
///
/// \param X
/// A 128-bit vector of [4 x float]. The values stored in bits [127:32] are
@@ -120,8 +117,7 @@
/// __m128d _mm_ceil_sd(__m128d X, __m128d Y);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VROUNDSD / ROUNDSD </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VROUNDSD / ROUNDSD </c> instruction.
///
/// \param X
/// A 128-bit vector of [2 x double]. The value stored in bits [127:64] is
@@ -144,8 +140,7 @@
/// __m128 _mm_floor_ps(__m128 X);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VROUNDPS / ROUNDPS </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VROUNDPS / ROUNDPS </c> instruction.
///
/// \param X
/// A 128-bit vector of [4 x float] values to be rounded down.
@@ -162,8 +157,7 @@
/// __m128d _mm_floor_pd(__m128d X);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VROUNDPD / ROUNDPD </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VROUNDPD / ROUNDPD </c> instruction.
///
/// \param X
/// A 128-bit vector of [2 x double].
@@ -182,8 +176,7 @@
/// __m128 _mm_floor_ss(__m128 X, __m128 Y);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VROUNDSS / ROUNDSS </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VROUNDSS / ROUNDSS </c> instruction.
///
/// \param X
/// A 128-bit vector of [4 x float]. The values stored in bits [127:32] are
@@ -208,8 +201,7 @@
/// __m128d _mm_floor_sd(__m128d X, __m128d Y);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VROUNDSD / ROUNDSD </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VROUNDSD / ROUNDSD </c> instruction.
///
/// \param X
/// A 128-bit vector of [2 x double]. The value stored in bits [127:64] is
@@ -233,8 +225,7 @@
/// __m128 _mm_round_ps(__m128 X, const int M);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VROUNDPS / ROUNDPS </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VROUNDPS / ROUNDPS </c> instruction.
///
/// \param X
/// A 128-bit vector of [4 x float].
@@ -269,8 +260,7 @@
/// __m128 _mm_round_ss(__m128 X, __m128 Y, const int M);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VROUNDSS / ROUNDSS </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VROUNDSS / ROUNDSS </c> instruction.
///
/// \param X
/// A 128-bit vector of [4 x float]. The values stored in bits [127:32] are
@@ -310,8 +300,7 @@
/// __m128d _mm_round_pd(__m128d X, const int M);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VROUNDPD / ROUNDPD </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VROUNDPD / ROUNDPD </c> instruction.
///
/// \param X
/// A 128-bit vector of [2 x double].
@@ -333,7 +322,6 @@
#define _mm_round_pd(X, M) __extension__ ({ \
(__m128d)__builtin_ia32_roundpd((__v2df)(__m128d)(X), (M)); })
-
/// \brief Copies the upper element of the first 128-bit vector operand to the
/// corresponding upper element of the 128-bit result vector of [2 x double].
/// Rounds the lower element of the second 128-bit vector operand to an
@@ -347,8 +335,7 @@
/// __m128d _mm_round_sd(__m128d X, __m128d Y, const int M);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VROUNDSD / ROUNDSD </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VROUNDSD / ROUNDSD </c> instruction.
///
/// \param X
/// A 128-bit vector of [2 x double]. The value stored in bits [127:64] is
@@ -388,8 +375,7 @@
/// __m128d _mm_blend_pd(__m128d V1, __m128d V2, const int M);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VBLENDPD / BLENDPD </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VBLENDPD / BLENDPD </c> instruction.
///
/// \param V1
/// A 128-bit vector of [2 x double].
@@ -419,8 +405,7 @@
/// __m128 _mm_blend_ps(__m128 V1, __m128 V2, const int M);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VBLENDPS / BLENDPS </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VBLENDPS / BLENDPS </c> instruction.
///
/// \param V1
/// A 128-bit vector of [4 x float].
@@ -447,8 +432,7 @@
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> VBLENDVPD / BLENDVPD </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VBLENDVPD / BLENDVPD </c> instruction.
///
/// \param __V1
/// A 128-bit vector of [2 x double].
@@ -475,8 +459,7 @@ _mm_blendv_pd (__m128d __V1, __m128d __V2, __m128d __M)
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> VBLENDVPS / BLENDVPS </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VBLENDVPS / BLENDVPS </c> instruction.
///
/// \param __V1
/// A 128-bit vector of [4 x float].
@@ -503,8 +486,7 @@ _mm_blendv_ps (__m128 __V1, __m128 __V2, __m128 __M)
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> VPBLENDVB / PBLENDVB </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPBLENDVB / PBLENDVB </c> instruction.
///
/// \param __V1
/// A 128-bit vector of [16 x i8].
@@ -535,8 +517,7 @@ _mm_blendv_epi8 (__m128i __V1, __m128i __V2, __m128i __M)
/// __m128i _mm_blend_epi16(__m128i V1, __m128i V2, const int M);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VPBLENDW / PBLENDW </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPBLENDW / PBLENDW </c> instruction.
///
/// \param V1
/// A 128-bit vector of [8 x i16].
@@ -569,8 +550,7 @@ _mm_blendv_epi8 (__m128i __V1, __m128i __V2, __m128i __M)
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> VPMULLD / PMULLD </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPMULLD / PMULLD </c> instruction.
///
/// \param __V1
/// A 128-bit integer vector.
@@ -589,8 +569,7 @@ _mm_mullo_epi32 (__m128i __V1, __m128i __V2)
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> VPMULDQ / PMULDQ </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPMULDQ / PMULDQ </c> instruction.
///
/// \param __V1
/// A 128-bit vector of [4 x i32].
@@ -617,8 +596,7 @@ _mm_mul_epi32 (__m128i __V1, __m128i __V2)
/// __m128 _mm_dp_ps(__m128 X, __m128 Y, const int M);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VDPPS / DPPS </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VDPPS / DPPS </c> instruction.
///
/// \param X
/// A 128-bit vector of [4 x float].
@@ -652,8 +630,7 @@ _mm_mul_epi32 (__m128i __V1, __m128i __V2)
/// __m128d _mm_dp_pd(__m128d X, __m128d Y, const int M);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VDPPD / DPPD </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VDPPD / DPPD </c> instruction.
///
/// \param X
/// A 128-bit vector of [2 x double].
@@ -680,8 +657,7 @@ _mm_mul_epi32 (__m128i __V1, __m128i __V2)
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> VMOVNTDQA / MOVNTDQA </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VMOVNTDQA / MOVNTDQA </c> instruction.
///
/// \param __V
/// A pointer to a 128-bit aligned memory location that contains the integer
@@ -701,8 +677,7 @@ _mm_stream_load_si128 (__m128i const *__V)
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> VPMINSB / PMINSB </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPMINSB / PMINSB </c> instruction.
///
/// \param __V1
/// A 128-bit vector of [16 x i8].
@@ -721,8 +696,7 @@ _mm_min_epi8 (__m128i __V1, __m128i __V2)
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> VPMAXSB / PMAXSB </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPMAXSB / PMAXSB </c> instruction.
///
/// \param __V1
/// A 128-bit vector of [16 x i8].
@@ -741,8 +715,7 @@ _mm_max_epi8 (__m128i __V1, __m128i __V2)
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> VPMINUW / PMINUW </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPMINUW / PMINUW </c> instruction.
///
/// \param __V1
/// A 128-bit vector of [8 x u16].
@@ -761,8 +734,7 @@ _mm_min_epu16 (__m128i __V1, __m128i __V2)
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> VPMAXUW / PMAXUW </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPMAXUW / PMAXUW </c> instruction.
///
/// \param __V1
/// A 128-bit vector of [8 x u16].
@@ -781,8 +753,7 @@ _mm_max_epu16 (__m128i __V1, __m128i __V2)
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> VPMINSD / PMINSD </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPMINSD / PMINSD </c> instruction.
///
/// \param __V1
/// A 128-bit vector of [4 x i32].
@@ -801,8 +772,7 @@ _mm_min_epi32 (__m128i __V1, __m128i __V2)
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> VPMAXSD / PMAXSD </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPMAXSD / PMAXSD </c> instruction.
///
/// \param __V1
/// A 128-bit vector of [4 x i32].
@@ -821,8 +791,7 @@ _mm_max_epi32 (__m128i __V1, __m128i __V2)
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> VPMINUD / PMINUD </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPMINUD / PMINUD </c> instruction.
///
/// \param __V1
/// A 128-bit vector of [4 x u32].
@@ -841,8 +810,7 @@ _mm_min_epu32 (__m128i __V1, __m128i __V2)
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> VPMAXUD / PMAXUD </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPMAXUD / PMAXUD </c> instruction.
///
/// \param __V1
/// A 128-bit vector of [4 x u32].
@@ -867,7 +835,7 @@ _mm_max_epu32 (__m128i __V1, __m128i __V2)
/// __m128 _mm_insert_ps(__m128 X, __m128 Y, const int N);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VINSERTPS </i> </c> instruction.
+/// This intrinsic corresponds to the <c> VINSERTPS </c> instruction.
///
/// \param X
/// A 128-bit vector source operand of [4 x float]. With the exception of
@@ -907,7 +875,7 @@ _mm_max_epu32 (__m128i __V1, __m128i __V2)
/// int _mm_extract_ps(__m128 X, const int N);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VEXTRACTPS / EXTRACTPS </i> </c>
+/// This intrinsic corresponds to the <c> VEXTRACTPS / EXTRACTPS </c>
/// instruction.
///
/// \param X
@@ -951,8 +919,7 @@ _mm_max_epu32 (__m128i __V1, __m128i __V2)
/// __m128i _mm_insert_epi8(__m128i X, int I, const int N);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VPINSRB / PINSRB </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPINSRB / PINSRB </c> instruction.
///
/// \param X
/// A 128-bit integer vector of [16 x i8]. This vector is copied to the
@@ -997,8 +964,7 @@ _mm_max_epu32 (__m128i __V1, __m128i __V2)
/// __m128i _mm_insert_epi32(__m128i X, int I, const int N);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VPINSRD / PINSRD </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPINSRD / PINSRD </c> instruction.
///
/// \param X
/// A 128-bit integer vector of [4 x i32]. This vector is copied to the
@@ -1009,7 +975,7 @@ _mm_max_epu32 (__m128i __V1, __m128i __V2)
/// specified by \a N.
/// \param N
/// An immediate value. Bits [1:0] specify the bit offset in the result at
-/// which the integer \a I is written.
+/// which the integer \a I is written. \n
/// 00: Bits [31:0] of the result are used for insertion. \n
/// 01: Bits [63:32] of the result are used for insertion. \n
/// 10: Bits [95:64] of the result are used for insertion. \n
@@ -1019,6 +985,7 @@ _mm_max_epu32 (__m128i __V1, __m128i __V2)
({ __v4si __a = (__v4si)(__m128i)(X); \
__a[(N) & 3] = (I); \
(__m128i)__a;}))
+
#ifdef __x86_64__
/// \brief Constructs a 128-bit vector of [2 x i64] by first making a copy of
/// the 128-bit integer vector parameter, and then inserting the 64-bit
@@ -1031,8 +998,7 @@ _mm_max_epu32 (__m128i __V1, __m128i __V2)
/// __m128i _mm_insert_epi64(__m128i X, long long I, const int N);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VPINSRQ / PINSRQ </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPINSRQ / PINSRQ </c> instruction.
///
/// \param X
/// A 128-bit integer vector of [2 x i64]. This vector is copied to the
@@ -1043,7 +1009,7 @@ _mm_max_epu32 (__m128i __V1, __m128i __V2)
/// specified by \a N.
/// \param N
/// An immediate value. Bit [0] specifies the bit offset in the result at
-/// which the integer \a I is written.
+/// which the integer \a I is written. \n
/// 0: Bits [63:0] of the result are used for insertion. \n
/// 1: Bits [127:64] of the result are used for insertion. \n
/// \returns A 128-bit integer vector containing the constructed values.
@@ -1065,14 +1031,13 @@ _mm_max_epu32 (__m128i __V1, __m128i __V2)
/// int _mm_extract_epi8(__m128i X, const int N);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VPEXTRB / PEXTRB </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPEXTRB / PEXTRB </c> instruction.
///
/// \param X
/// A 128-bit integer vector.
/// \param N
-/// An immediate value. Bits [3:0] specify which 8-bit vector element
-/// from the argument \a X to extract and copy to the result. \n
+/// An immediate value. Bits [3:0] specify which 8-bit vector element from
+/// the argument \a X to extract and copy to the result. \n
/// 0000: Bits [7:0] of parameter \a X are extracted. \n
/// 0001: Bits [15:8] of the parameter \a X are extracted. \n
/// 0010: Bits [23:16] of the parameter \a X are extracted. \n
@@ -1105,14 +1070,13 @@ _mm_max_epu32 (__m128i __V1, __m128i __V2)
/// int _mm_extract_epi32(__m128i X, const int N);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VPEXTRD / PEXTRD </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPEXTRD / PEXTRD </c> instruction.
///
/// \param X
/// A 128-bit integer vector.
/// \param N
-/// An immediate value. Bits [1:0] specify which 32-bit vector element
-/// from the argument \a X to extract and copy to the result. \n
+/// An immediate value. Bits [1:0] specify which 32-bit vector element from
+/// the argument \a X to extract and copy to the result. \n
/// 00: Bits [31:0] of the parameter \a X are extracted. \n
/// 01: Bits [63:32] of the parameter \a X are extracted. \n
/// 10: Bits [95:64] of the parameter \a X are extracted. \n
@@ -1122,6 +1086,7 @@ _mm_max_epu32 (__m128i __V1, __m128i __V2)
#define _mm_extract_epi32(X, N) (__extension__ \
({ __v4si __a = (__v4si)(__m128i)(X); \
(int)__a[(N) & 3];}))
+
#ifdef __x86_64__
/// \brief Extracts a 64-bit element from the 128-bit integer vector of
/// [2 x i64], using the immediate value parameter \a N as a selector.
@@ -1132,14 +1097,13 @@ _mm_max_epu32 (__m128i __V1, __m128i __V2)
/// long long _mm_extract_epi64(__m128i X, const int N);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VPEXTRQ / PEXTRQ </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPEXTRQ / PEXTRQ </c> instruction.
///
/// \param X
/// A 128-bit integer vector.
/// \param N
-/// An immediate value. Bit [0] specifies which 64-bit vector element
-/// from the argument \a X to return. \n
+/// An immediate value. Bit [0] specifies which 64-bit vector element from
+/// the argument \a X to return. \n
/// 0: Bits [63:0] are returned. \n
/// 1: Bits [127:64] are returned. \n
/// \returns A 64-bit integer.
@@ -1154,8 +1118,7 @@ _mm_max_epu32 (__m128i __V1, __m128i __V2)
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> VPTEST / PTEST </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPTEST / PTEST </c> instruction.
///
/// \param __M
/// A 128-bit integer vector containing the bits to be tested.
@@ -1173,8 +1136,7 @@ _mm_testz_si128(__m128i __M, __m128i __V)
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> VPTEST / PTEST </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPTEST / PTEST </c> instruction.
///
/// \param __M
/// A 128-bit integer vector containing the bits to be tested.
@@ -1192,8 +1154,7 @@ _mm_testc_si128(__m128i __M, __m128i __V)
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> VPTEST / PTEST </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPTEST / PTEST </c> instruction.
///
/// \param __M
/// A 128-bit integer vector containing the bits to be tested.
@@ -1216,8 +1177,7 @@ _mm_testnzc_si128(__m128i __M, __m128i __V)
/// int _mm_test_all_ones(__m128i V);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VPTEST / PTEST </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPTEST / PTEST </c> instruction.
///
/// \param V
/// A 128-bit integer vector containing the bits to be tested.
@@ -1234,8 +1194,7 @@ _mm_testnzc_si128(__m128i __M, __m128i __V)
/// int _mm_test_mix_ones_zeros(__m128i M, __m128i V);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VPTEST / PTEST </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPTEST / PTEST </c> instruction.
///
/// \param M
/// A 128-bit integer vector containing the bits to be tested.
@@ -1254,8 +1213,7 @@ _mm_testnzc_si128(__m128i __M, __m128i __V)
/// int _mm_test_all_zeros(__m128i M, __m128i V);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VPTEST / PTEST </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPTEST / PTEST </c> instruction.
///
/// \param M
/// A 128-bit integer vector containing the bits to be tested.
@@ -1270,8 +1228,7 @@ _mm_testnzc_si128(__m128i __M, __m128i __V)
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> VPCMPEQQ / PCMPEQQ </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPCMPEQQ / PCMPEQQ </c> instruction.
///
/// \param __V1
/// A 128-bit integer vector.
@@ -1292,8 +1249,7 @@ _mm_cmpeq_epi64(__m128i __V1, __m128i __V2)
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> VPMOVSXBW / PMOVSXBW </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPMOVSXBW / PMOVSXBW </c> instruction.
///
/// \param __V
/// A 128-bit vector of [16 x i8]. The lower eight 8-bit elements are sign-
@@ -1314,8 +1270,7 @@ _mm_cvtepi8_epi16(__m128i __V)
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> VPMOVSXBD / PMOVSXBD </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPMOVSXBD / PMOVSXBD </c> instruction.
///
/// \param __V
/// A 128-bit vector of [16 x i8]. The lower four 8-bit elements are sign-
@@ -1336,8 +1291,7 @@ _mm_cvtepi8_epi32(__m128i __V)
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> VPMOVSXBQ / PMOVSXBQ </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPMOVSXBQ / PMOVSXBQ </c> instruction.
///
/// \param __V
/// A 128-bit vector of [16 x i8]. The lower two 8-bit elements are sign-
@@ -1358,8 +1312,7 @@ _mm_cvtepi8_epi64(__m128i __V)
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> VPMOVSXWD / PMOVSXWD </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPMOVSXWD / PMOVSXWD </c> instruction.
///
/// \param __V
/// A 128-bit vector of [8 x i16]. The lower four 16-bit elements are sign-
@@ -1378,8 +1331,7 @@ _mm_cvtepi16_epi32(__m128i __V)
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> VPMOVSXWQ / PMOVSXWQ </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPMOVSXWQ / PMOVSXWQ </c> instruction.
///
/// \param __V
/// A 128-bit vector of [8 x i16]. The lower two 16-bit elements are sign-
@@ -1398,8 +1350,7 @@ _mm_cvtepi16_epi64(__m128i __V)
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> VPMOVSXDQ / PMOVSXDQ </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPMOVSXDQ / PMOVSXDQ </c> instruction.
///
/// \param __V
/// A 128-bit vector of [4 x i32]. The lower two 32-bit elements are sign-
@@ -1419,8 +1370,7 @@ _mm_cvtepi32_epi64(__m128i __V)
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> VPMOVZXBW / PMOVZXBW </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPMOVZXBW / PMOVZXBW </c> instruction.
///
/// \param __V
/// A 128-bit vector of [16 x i8]. The lower eight 8-bit elements are zero-
@@ -1439,8 +1389,7 @@ _mm_cvtepu8_epi16(__m128i __V)
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> VPMOVZXBD / PMOVZXBD </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPMOVZXBD / PMOVZXBD </c> instruction.
///
/// \param __V
/// A 128-bit vector of [16 x i8]. The lower four 8-bit elements are zero-
@@ -1459,8 +1408,7 @@ _mm_cvtepu8_epi32(__m128i __V)
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> VPMOVZXBQ / PMOVZXBQ </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPMOVZXBQ / PMOVZXBQ </c> instruction.
///
/// \param __V
/// A 128-bit vector of [16 x i8]. The lower two 8-bit elements are zero-
@@ -1479,8 +1427,7 @@ _mm_cvtepu8_epi64(__m128i __V)
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> VPMOVZXWD / PMOVZXWD </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPMOVZXWD / PMOVZXWD </c> instruction.
///
/// \param __V
/// A 128-bit vector of [8 x i16]. The lower four 16-bit elements are zero-
@@ -1499,8 +1446,7 @@ _mm_cvtepu16_epi32(__m128i __V)
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> VPMOVZXWQ / PMOVZXWQ </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPMOVZXWQ / PMOVZXWQ </c> instruction.
///
/// \param __V
/// A 128-bit vector of [8 x i16]. The lower two 16-bit elements are zero-
@@ -1519,8 +1465,7 @@ _mm_cvtepu16_epi64(__m128i __V)
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> VPMOVZXDQ / PMOVZXDQ </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPMOVZXDQ / PMOVZXDQ </c> instruction.
///
/// \param __V
/// A 128-bit vector of [4 x i32]. The lower two 32-bit elements are zero-
@@ -1540,8 +1485,7 @@ _mm_cvtepu32_epi64(__m128i __V)
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> VPACKUSDW / PACKUSDW </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPACKUSDW / PACKUSDW </c> instruction.
///
/// \param __V1
/// A 128-bit vector of [4 x i32]. Each 32-bit element is treated as a
@@ -1574,8 +1518,7 @@ _mm_packus_epi32(__m128i __V1, __m128i __V2)
/// __m128i _mm_mpsadbw_epu8(__m128i X, __m128i Y, const int M);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VMPSADBW / MPSADBW </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VMPSADBW / MPSADBW </c> instruction.
///
/// \param X
/// A 128-bit vector of [16 x i8].
@@ -1608,7 +1551,7 @@ _mm_packus_epi32(__m128i __V1, __m128i __V2)
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> VPHMINPOSUW / PHMINPOSUW </i> </c>
+/// This intrinsic corresponds to the <c> VPHMINPOSUW / PHMINPOSUW </c>
/// instruction.
///
/// \param __V
@@ -1668,7 +1611,7 @@ _mm_minpos_epu16(__m128i __V)
/// __m128i _mm_cmpistrm(__m128i A, __m128i B, const int M);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VPCMPISTRM / PCMPISTRM </i> </c>
+/// This intrinsic corresponds to the <c> VPCMPISTRM / PCMPISTRM </c>
/// instruction.
///
/// \param A
@@ -1724,7 +1667,7 @@ _mm_minpos_epu16(__m128i __V)
/// int _mm_cmpistri(__m128i A, __m128i B, const int M);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VPCMPISTRI / PCMPISTRI </i> </c>
+/// This intrinsic corresponds to the <c> VPCMPISTRI / PCMPISTRI </c>
/// instruction.
///
/// \param A
@@ -1778,7 +1721,7 @@ _mm_minpos_epu16(__m128i __V)
/// __m128i _mm_cmpestrm(__m128i A, int LA, __m128i B, int LB, const int M);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VPCMPESTRM / PCMPESTRM </i> </c>
+/// This intrinsic corresponds to the <c> VPCMPESTRM / PCMPESTRM </c>
/// instruction.
///
/// \param A
@@ -1839,7 +1782,7 @@ _mm_minpos_epu16(__m128i __V)
/// int _mm_cmpestri(__m128i A, int LA, __m128i B, int LB, const int M);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VPCMPESTRI / PCMPESTRI </i> </c>
+/// This intrinsic corresponds to the <c> VPCMPESTRI / PCMPESTRI </c>
/// instruction.
///
/// \param A
@@ -1899,7 +1842,7 @@ _mm_minpos_epu16(__m128i __V)
/// int _mm_cmpistra(__m128i A, __m128i B, const int M);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VPCMPISTRI / PCMPISTRI </i> </c>
+/// This intrinsic corresponds to the <c> VPCMPISTRI / PCMPISTRI </c>
/// instruction.
///
/// \param A
@@ -1949,7 +1892,7 @@ _mm_minpos_epu16(__m128i __V)
/// int _mm_cmpistrc(__m128i A, __m128i B, const int M);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VPCMPISTRI / PCMPISTRI </i> </c>
+/// This intrinsic corresponds to the <c> VPCMPISTRI / PCMPISTRI </c>
/// instruction.
///
/// \param A
@@ -1997,7 +1940,7 @@ _mm_minpos_epu16(__m128i __V)
/// int _mm_cmpistro(__m128i A, __m128i B, const int M);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VPCMPISTRI / PCMPISTRI </i> </c>
+/// This intrinsic corresponds to the <c> VPCMPISTRI / PCMPISTRI </c>
/// instruction.
///
/// \param A
@@ -2046,7 +1989,7 @@ _mm_minpos_epu16(__m128i __V)
/// int _mm_cmpistrs(__m128i A, __m128i B, const int M);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VPCMPISTRI / PCMPISTRI </i> </c>
+/// This intrinsic corresponds to the <c> VPCMPISTRI / PCMPISTRI </c>
/// instruction.
///
/// \param A
@@ -2096,7 +2039,7 @@ _mm_minpos_epu16(__m128i __V)
/// int _mm_cmpistrz(__m128i A, __m128i B, const int M);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VPCMPISTRI / PCMPISTRI </i> </c>
+/// This intrinsic corresponds to the <c> VPCMPISTRI / PCMPISTRI </c>
/// instruction.
///
/// \param A
@@ -2146,7 +2089,7 @@ _mm_minpos_epu16(__m128i __V)
/// int _mm_cmpestra(__m128i A, int LA, __m128i B, int LB, const int M);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VPCMPESTRI / PCMPESTRI </i> </c>
+/// This intrinsic corresponds to the <c> VPCMPESTRI / PCMPESTRI </c>
/// instruction.
///
/// \param A
@@ -2201,7 +2144,7 @@ _mm_minpos_epu16(__m128i __V)
/// int _mm_cmpestrc(__m128i A, int LA, __m128i B, int LB, const int M);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VPCMPESTRI / PCMPESTRI </i> </c>
+/// This intrinsic corresponds to the <c> VPCMPESTRI / PCMPESTRI </c>
/// instruction.
///
/// \param A
@@ -2243,6 +2186,7 @@ _mm_minpos_epu16(__m128i __V)
(int)__builtin_ia32_pcmpestric128((__v16qi)(__m128i)(A), (int)(LA), \
(__v16qi)(__m128i)(B), (int)(LB), \
(int)(M))
+
/// \brief Uses the immediate operand \a M to perform a comparison of string
/// data with explicitly defined lengths that is contained in source operands
/// \a A and \a B. Returns bit 0 of the resulting bit mask.
@@ -2253,7 +2197,7 @@ _mm_minpos_epu16(__m128i __V)
/// int _mm_cmpestro(__m128i A, int LA, __m128i B, int LB, const int M);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VPCMPESTRI / PCMPESTRI </i> </c>
+/// This intrinsic corresponds to the <c> VPCMPESTRI / PCMPESTRI </c>
/// instruction.
///
/// \param A
@@ -2307,7 +2251,7 @@ _mm_minpos_epu16(__m128i __V)
/// int _mm_cmpestrs(__m128i A, int LA, __m128i B, int LB, const int M);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VPCMPESTRI / PCMPESTRI </i> </c>
+/// This intrinsic corresponds to the <c> VPCMPESTRI / PCMPESTRI </c>
/// instruction.
///
/// \param A
@@ -2362,7 +2306,7 @@ _mm_minpos_epu16(__m128i __V)
/// int _mm_cmpestrz(__m128i A, int LA, __m128i B, int LB, const int M);
/// \endcode
///
-/// This intrinsic corresponds to the <c> <i> VPCMPESTRI </i> </c> instruction.
+/// This intrinsic corresponds to the <c> VPCMPESTRI </c> instruction.
///
/// \param A
/// A 128-bit integer vector containing one of the source operands to be
@@ -2412,8 +2356,7 @@ _mm_minpos_epu16(__m128i __V)
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> VPCMPGTQ / PCMPGTQ </i> </c>
-/// instruction.
+/// This intrinsic corresponds to the <c> VPCMPGTQ / PCMPGTQ </c> instruction.
///
/// \param __V1
/// A 128-bit integer vector.
@@ -2432,7 +2375,7 @@ _mm_cmpgt_epi64(__m128i __V1, __m128i __V2)
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> CRC32B </i> </c> instruction.
+/// This intrinsic corresponds to the <c> CRC32B </c> instruction.
///
/// \param __C
/// An unsigned integer operand to add to the CRC-32C checksum of operand
@@ -2452,7 +2395,7 @@ _mm_crc32_u8(unsigned int __C, unsigned char __D)
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> CRC32W </i> </c> instruction.
+/// This intrinsic corresponds to the <c> CRC32W </c> instruction.
///
/// \param __C
/// An unsigned integer operand to add to the CRC-32C checksum of operand
@@ -2472,7 +2415,7 @@ _mm_crc32_u16(unsigned int __C, unsigned short __D)
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> CRC32L </i> </c> instruction.
+/// This intrinsic corresponds to the <c> CRC32L </c> instruction.
///
/// \param __C
/// An unsigned integer operand to add to the CRC-32C checksum of operand
@@ -2493,7 +2436,7 @@ _mm_crc32_u32(unsigned int __C, unsigned int __D)
///
/// \headerfile <x86intrin.h>
///
-/// This intrinsic corresponds to the <c> <i> CRC32Q </i> </c> instruction.
+/// This intrinsic corresponds to the <c> CRC32Q </c> instruction.
///
/// \param __C
/// An unsigned integer operand to add to the CRC-32C checksum of operand
diff --git a/lib/Headers/xmmintrin.h b/lib/Headers/xmmintrin.h
index bb8e29cd9052..5c312c08efb6 100644
--- a/lib/Headers/xmmintrin.h
+++ b/lib/Headers/xmmintrin.h
@@ -2540,7 +2540,7 @@ void _mm_setcsr(unsigned int __i);
/// A 128-bit vector of [4 x float].
/// \param mask
/// An immediate value containing an 8-bit value specifying which elements to
-/// copy from \ a and \a b. \n
+/// copy from \a a and \a b. \n
/// Bits [3:0] specify the values copied from operand \a a. \n
/// Bits [7:4] specify the values copied from operand \a b. \n
/// The destinations within the 128-bit destination are assigned values as
diff --git a/lib/Index/CommentToXML.cpp b/lib/Index/CommentToXML.cpp
index 08acc96c4efb..e568c838b7b0 100644
--- a/lib/Index/CommentToXML.cpp
+++ b/lib/Index/CommentToXML.cpp
@@ -592,12 +592,10 @@ void CommentASTToXMLConverter::formatTextOfDeclaration(
unsigned Offset = 0;
unsigned Length = Declaration.size();
- bool IncompleteFormat = false;
format::FormatStyle Style = format::getLLVMStyle();
Style.FixNamespaceComments = false;
tooling::Replacements Replaces =
- reformat(Style, StringDecl, tooling::Range(Offset, Length), "xmldecl.xd",
- &IncompleteFormat);
+ reformat(Style, StringDecl, tooling::Range(Offset, Length), "xmldecl.xd");
auto FormattedStringDecl = applyAllReplacements(StringDecl, Replaces);
if (static_cast<bool>(FormattedStringDecl)) {
Declaration = *FormattedStringDecl;
diff --git a/lib/Index/IndexDecl.cpp b/lib/Index/IndexDecl.cpp
index dae0cdc0d9c9..0e893505516f 100644
--- a/lib/Index/IndexDecl.cpp
+++ b/lib/Index/IndexDecl.cpp
@@ -495,8 +495,18 @@ public:
ClassTemplateSpecializationDecl *D) {
// FIXME: Notify subsequent callbacks if info comes from implicit
// instantiation.
- if (D->isThisDeclarationADefinition())
- IndexCtx.indexTagDecl(D);
+ if (D->isThisDeclarationADefinition()) {
+ llvm::PointerUnion<ClassTemplateDecl *,
+ ClassTemplatePartialSpecializationDecl *>
+ Template = D->getSpecializedTemplateOrPartial();
+ const Decl *SpecializationOf =
+ Template.is<ClassTemplateDecl *>()
+ ? (Decl *)Template.get<ClassTemplateDecl *>()
+ : Template.get<ClassTemplatePartialSpecializationDecl *>();
+ IndexCtx.indexTagDecl(
+ D, SymbolRelation(SymbolRoleSet(SymbolRole::RelationSpecializationOf),
+ SpecializationOf));
+ }
return true;
}
diff --git a/lib/Index/IndexSymbol.cpp b/lib/Index/IndexSymbol.cpp
index fe3c17845daa..ea66b7017951 100644
--- a/lib/Index/IndexSymbol.cpp
+++ b/lib/Index/IndexSymbol.cpp
@@ -346,6 +346,7 @@ bool index::applyForEachSymbolRoleInterruptible(SymbolRoleSet Roles,
APPLY_FOR_ROLE(RelationAccessorOf);
APPLY_FOR_ROLE(RelationContainedBy);
APPLY_FOR_ROLE(RelationIBTypeOf);
+ APPLY_FOR_ROLE(RelationSpecializationOf);
#undef APPLY_FOR_ROLE
@@ -386,6 +387,7 @@ void index::printSymbolRoles(SymbolRoleSet Roles, raw_ostream &OS) {
case SymbolRole::RelationAccessorOf: OS << "RelAcc"; break;
case SymbolRole::RelationContainedBy: OS << "RelCont"; break;
case SymbolRole::RelationIBTypeOf: OS << "RelIBType"; break;
+ case SymbolRole::RelationSpecializationOf: OS << "RelSpecialization"; break;
}
});
}
diff --git a/lib/Index/IndexTypeSourceInfo.cpp b/lib/Index/IndexTypeSourceInfo.cpp
index 0645d5be5268..a3566a9f2ae8 100644
--- a/lib/Index/IndexTypeSourceInfo.cpp
+++ b/lib/Index/IndexTypeSourceInfo.cpp
@@ -208,11 +208,12 @@ void IndexingContext::indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
}
}
-void IndexingContext::indexTagDecl(const TagDecl *D) {
+void IndexingContext::indexTagDecl(const TagDecl *D,
+ ArrayRef<SymbolRelation> Relations) {
if (!shouldIndexFunctionLocalSymbols() && isFunctionLocalSymbol(D))
return;
- if (handleDecl(D)) {
+ if (handleDecl(D, /*Roles=*/SymbolRoleSet(), Relations)) {
if (D->isThisDeclarationADefinition()) {
indexNestedNameSpecifierLoc(D->getQualifierLoc(), D);
if (auto CXXRD = dyn_cast<CXXRecordDecl>(D)) {
diff --git a/lib/Index/IndexingContext.cpp b/lib/Index/IndexingContext.cpp
index f393b11ab884..85574d0a314d 100644
--- a/lib/Index/IndexingContext.cpp
+++ b/lib/Index/IndexingContext.cpp
@@ -233,6 +233,7 @@ static bool shouldReportOccurrenceForSystemDeclOnlyMode(
case SymbolRole::RelationReceivedBy:
case SymbolRole::RelationCalledBy:
case SymbolRole::RelationContainedBy:
+ case SymbolRole::RelationSpecializationOf:
return true;
}
llvm_unreachable("Unsupported SymbolRole value!");
diff --git a/lib/Index/IndexingContext.h b/lib/Index/IndexingContext.h
index 933b0a2cda07..1ebf6f9ce67a 100644
--- a/lib/Index/IndexingContext.h
+++ b/lib/Index/IndexingContext.h
@@ -80,7 +80,8 @@ public:
bool indexDecl(const Decl *D);
- void indexTagDecl(const TagDecl *D);
+ void indexTagDecl(const TagDecl *D,
+ ArrayRef<SymbolRelation> Relations = None);
void indexTypeSourceInfo(TypeSourceInfo *TInfo, const NamedDecl *Parent,
const DeclContext *DC = nullptr,
diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp
index 4c051939471c..003c9b5eed1b 100644
--- a/lib/Lex/Lexer.cpp
+++ b/lib/Lex/Lexer.cpp
@@ -1171,6 +1171,8 @@ const char *Lexer::SkipEscapedNewLines(const char *P) {
// If not a trigraph for escape, bail out.
if (P[1] != '?' || P[2] != '/')
return P;
+ // FIXME: Take LangOpts into account; the language might not
+ // support trigraphs.
AfterEscape = P+3;
} else {
return P;
@@ -1282,12 +1284,6 @@ Slash:
Size += EscapedNewLineSize;
Ptr += EscapedNewLineSize;
- // If the char that we finally got was a \n, then we must have had
- // something like \<newline><newline>. We don't want to consume the
- // second newline.
- if (*Ptr == '\n' || *Ptr == '\r' || *Ptr == '\0')
- return ' ';
-
// Use slow version to accumulate a correct size field.
return getCharAndSizeSlow(Ptr, Size, Tok);
}
@@ -1338,12 +1334,6 @@ Slash:
Size += EscapedNewLineSize;
Ptr += EscapedNewLineSize;
- // If the char that we finally got was a \n, then we must have had
- // something like \<newline><newline>. We don't want to consume the
- // second newline.
- if (*Ptr == '\n' || *Ptr == '\r' || *Ptr == '\0')
- return ' ';
-
// Use slow version to accumulate a correct size field.
return getCharAndSizeSlowNoWarn(Ptr, Size, LangOpts);
}
@@ -2070,8 +2060,11 @@ bool Lexer::SkipLineComment(Token &Result, const char *CurPtr,
// Scan over the body of the comment. The common case, when scanning, is that
// the comment contains normal ascii characters with nothing interesting in
// them. As such, optimize for this case with the inner loop.
+ //
+ // This loop terminates with CurPtr pointing at the newline (or end of buffer)
+ // character that ends the line comment.
char C;
- do {
+ while (true) {
C = *CurPtr;
// Skip over characters in the fast loop.
while (C != 0 && // Potentially EOF.
@@ -2088,10 +2081,12 @@ bool Lexer::SkipLineComment(Token &Result, const char *CurPtr,
HasSpace = true;
}
- if (*EscapePtr == '\\') // Escaped newline.
+ if (*EscapePtr == '\\')
+ // Escaped newline.
CurPtr = EscapePtr;
else if (EscapePtr[0] == '/' && EscapePtr[-1] == '?' &&
- EscapePtr[-2] == '?') // Trigraph-escaped newline.
+ EscapePtr[-2] == '?' && LangOpts.Trigraphs)
+ // Trigraph-escaped newline.
CurPtr = EscapePtr-2;
else
break; // This is a newline, we're done.
@@ -2140,9 +2135,9 @@ bool Lexer::SkipLineComment(Token &Result, const char *CurPtr,
}
}
- if (CurPtr == BufferEnd+1) {
- --CurPtr;
- break;
+ if (C == '\r' || C == '\n' || CurPtr == BufferEnd + 1) {
+ --CurPtr;
+ break;
}
if (C == '\0' && isCodeCompletionPoint(CurPtr-1)) {
@@ -2150,8 +2145,7 @@ bool Lexer::SkipLineComment(Token &Result, const char *CurPtr,
cutOffLexing();
return false;
}
-
- } while (C != '\n' && C != '\r');
+ }
// Found but did not consume the newline. Notify comment handlers about the
// comment unless we're in a #if 0 block.
@@ -2722,6 +2716,37 @@ bool Lexer::HandleEndOfConflictMarker(const char *CurPtr) {
return false;
}
+static const char *findPlaceholderEnd(const char *CurPtr,
+ const char *BufferEnd) {
+ if (CurPtr == BufferEnd)
+ return nullptr;
+ BufferEnd -= 1; // Scan until the second last character.
+ for (; CurPtr != BufferEnd; ++CurPtr) {
+ if (CurPtr[0] == '#' && CurPtr[1] == '>')
+ return CurPtr + 2;
+ }
+ return nullptr;
+}
+
+bool Lexer::lexEditorPlaceholder(Token &Result, const char *CurPtr) {
+ assert(CurPtr[-1] == '<' && CurPtr[0] == '#' && "Not a placeholder!");
+ if (!PP || LexingRawMode)
+ return false;
+ const char *End = findPlaceholderEnd(CurPtr + 1, BufferEnd);
+ if (!End)
+ return false;
+ const char *Start = CurPtr - 1;
+ if (!LangOpts.AllowEditorPlaceholders)
+ Diag(Start, diag::err_placeholder_in_source);
+ Result.startToken();
+ FormTokenWithChars(Result, End, tok::raw_identifier);
+ Result.setRawIdentifierData(Start);
+ PP->LookUpIdentifierInfo(Result);
+ Result.setFlag(Token::IsEditorPlaceholder);
+ BufferPtr = End;
+ return true;
+}
+
bool Lexer::isCodeCompletionPoint(const char *CurPtr) const {
if (PP && PP->isCodeCompletionEnabled()) {
SourceLocation Loc = FileLoc.getLocWithOffset(CurPtr-BufferStart);
@@ -3479,6 +3504,8 @@ LexNextToken:
} else if (LangOpts.Digraphs && Char == '%') { // '<%' -> '{'
CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
Kind = tok::l_brace;
+ } else if (Char == '#' && lexEditorPlaceholder(Result, CurPtr)) {
+ return true;
} else {
Kind = tok::less;
}
diff --git a/lib/Lex/ModuleMap.cpp b/lib/Lex/ModuleMap.cpp
index 4f3db8dd6436..5b60ed3f812a 100644
--- a/lib/Lex/ModuleMap.cpp
+++ b/lib/Lex/ModuleMap.cpp
@@ -2002,9 +2002,8 @@ void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
}
if (!Dir) {
- Diags.Report(DirNameLoc, diag::err_mmap_umbrella_dir_not_found)
+ Diags.Report(DirNameLoc, diag::warn_mmap_umbrella_dir_not_found)
<< DirName;
- HadError = true;
return;
}
diff --git a/lib/Lex/PPLexerChange.cpp b/lib/Lex/PPLexerChange.cpp
index 4db17c344b67..cf0c953b61f8 100644
--- a/lib/Lex/PPLexerChange.cpp
+++ b/lib/Lex/PPLexerChange.cpp
@@ -303,9 +303,8 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) {
if (const FileEntry *FE = CurPPLexer->getFileEntry()) {
HeaderInfo.SetFileControllingMacro(FE, ControllingMacro);
if (MacroInfo *MI =
- getMacroInfo(const_cast<IdentifierInfo*>(ControllingMacro))) {
- MI->UsedForHeaderGuard = true;
- }
+ getMacroInfo(const_cast<IdentifierInfo*>(ControllingMacro)))
+ MI->setUsedForHeaderGuard(true);
if (const IdentifierInfo *DefinedMacro =
CurPPLexer->MIOpt.GetDefinedMacro()) {
if (!isMacroDefined(ControllingMacro) &&
diff --git a/lib/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp
index c8de6b35f9ef..c34cd09a6238 100644
--- a/lib/Parse/ParsePragma.cpp
+++ b/lib/Parse/ParsePragma.cpp
@@ -183,6 +183,17 @@ private:
Sema &Actions;
};
+/// PragmaAttributeHandler - "\#pragma clang attribute ...".
+struct PragmaAttributeHandler : public PragmaHandler {
+ PragmaAttributeHandler(AttributeFactory &AttrFactory)
+ : PragmaHandler("attribute"), AttributesForPragmaAttribute(AttrFactory) {}
+ void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+ Token &FirstToken) override;
+
+ /// A pool of attributes that were parsed in \#pragma clang attribute.
+ ParsedAttributes AttributesForPragmaAttribute;
+};
+
} // end namespace
void Parser::initializePragmaHandlers() {
@@ -275,6 +286,9 @@ void Parser::initializePragmaHandlers() {
FPHandler.reset(new PragmaFPHandler());
PP.AddPragmaHandler("clang", FPHandler.get());
+
+ AttributePragmaHandler.reset(new PragmaAttributeHandler(AttrFactory));
+ PP.AddPragmaHandler("clang", AttributePragmaHandler.get());
}
void Parser::resetPragmaHandlers() {
@@ -356,6 +370,9 @@ void Parser::resetPragmaHandlers() {
PP.RemovePragmaHandler("clang", FPHandler.get());
FPHandler.reset();
+
+ PP.RemovePragmaHandler("clang", AttributePragmaHandler.get());
+ AttributePragmaHandler.reset();
}
/// \brief Handle the annotation token produced for #pragma unused(...)
@@ -966,6 +983,422 @@ bool Parser::HandlePragmaLoopHint(LoopHint &Hint) {
return true;
}
+namespace {
+struct PragmaAttributeInfo {
+ enum ActionType { Push, Pop };
+ ParsedAttributes &Attributes;
+ ActionType Action;
+ ArrayRef<Token> Tokens;
+
+ PragmaAttributeInfo(ParsedAttributes &Attributes) : Attributes(Attributes) {}
+};
+
+#include "clang/Parse/AttrSubMatchRulesParserStringSwitches.inc"
+
+} // end anonymous namespace
+
+static StringRef getIdentifier(const Token &Tok) {
+ if (Tok.is(tok::identifier))
+ return Tok.getIdentifierInfo()->getName();
+ const char *S = tok::getKeywordSpelling(Tok.getKind());
+ if (!S)
+ return "";
+ return S;
+}
+
+static bool isAbstractAttrMatcherRule(attr::SubjectMatchRule Rule) {
+ using namespace attr;
+ switch (Rule) {
+#define ATTR_MATCH_RULE(Value, Spelling, IsAbstract) \
+ case Value: \
+ return IsAbstract;
+#include "clang/Basic/AttrSubMatchRulesList.inc"
+ }
+ llvm_unreachable("Invalid attribute subject match rule");
+ return false;
+}
+
+static void diagnoseExpectedAttributeSubjectSubRule(
+ Parser &PRef, attr::SubjectMatchRule PrimaryRule, StringRef PrimaryRuleName,
+ SourceLocation SubRuleLoc) {
+ auto Diagnostic =
+ PRef.Diag(SubRuleLoc,
+ diag::err_pragma_attribute_expected_subject_sub_identifier)
+ << PrimaryRuleName;
+ if (const char *SubRules = validAttributeSubjectMatchSubRules(PrimaryRule))
+ Diagnostic << /*SubRulesSupported=*/1 << SubRules;
+ else
+ Diagnostic << /*SubRulesSupported=*/0;
+}
+
+static void diagnoseUnknownAttributeSubjectSubRule(
+ Parser &PRef, attr::SubjectMatchRule PrimaryRule, StringRef PrimaryRuleName,
+ StringRef SubRuleName, SourceLocation SubRuleLoc) {
+
+ auto Diagnostic =
+ PRef.Diag(SubRuleLoc, diag::err_pragma_attribute_unknown_subject_sub_rule)
+ << SubRuleName << PrimaryRuleName;
+ if (const char *SubRules = validAttributeSubjectMatchSubRules(PrimaryRule))
+ Diagnostic << /*SubRulesSupported=*/1 << SubRules;
+ else
+ Diagnostic << /*SubRulesSupported=*/0;
+}
+
+bool Parser::ParsePragmaAttributeSubjectMatchRuleSet(
+ attr::ParsedSubjectMatchRuleSet &SubjectMatchRules, SourceLocation &AnyLoc,
+ SourceLocation &LastMatchRuleEndLoc) {
+ bool IsAny = false;
+ BalancedDelimiterTracker AnyParens(*this, tok::l_paren);
+ if (getIdentifier(Tok) == "any") {
+ AnyLoc = ConsumeToken();
+ IsAny = true;
+ if (AnyParens.expectAndConsume())
+ return true;
+ }
+
+ do {
+ // Parse the subject matcher rule.
+ StringRef Name = getIdentifier(Tok);
+ if (Name.empty()) {
+ Diag(Tok, diag::err_pragma_attribute_expected_subject_identifier);
+ return true;
+ }
+ std::pair<Optional<attr::SubjectMatchRule>,
+ Optional<attr::SubjectMatchRule> (*)(StringRef, bool)>
+ Rule = isAttributeSubjectMatchRule(Name);
+ if (!Rule.first) {
+ Diag(Tok, diag::err_pragma_attribute_unknown_subject_rule) << Name;
+ return true;
+ }
+ attr::SubjectMatchRule PrimaryRule = *Rule.first;
+ SourceLocation RuleLoc = ConsumeToken();
+
+ BalancedDelimiterTracker Parens(*this, tok::l_paren);
+ if (isAbstractAttrMatcherRule(PrimaryRule)) {
+ if (Parens.expectAndConsume())
+ return true;
+ } else if (Parens.consumeOpen()) {
+ if (!SubjectMatchRules
+ .insert(
+ std::make_pair(PrimaryRule, SourceRange(RuleLoc, RuleLoc)))
+ .second)
+ Diag(RuleLoc, diag::err_pragma_attribute_duplicate_subject)
+ << Name
+ << FixItHint::CreateRemoval(SourceRange(
+ RuleLoc, Tok.is(tok::comma) ? Tok.getLocation() : RuleLoc));
+ LastMatchRuleEndLoc = RuleLoc;
+ continue;
+ }
+
+ // Parse the sub-rules.
+ StringRef SubRuleName = getIdentifier(Tok);
+ if (SubRuleName.empty()) {
+ diagnoseExpectedAttributeSubjectSubRule(*this, PrimaryRule, Name,
+ Tok.getLocation());
+ return true;
+ }
+ attr::SubjectMatchRule SubRule;
+ if (SubRuleName == "unless") {
+ SourceLocation SubRuleLoc = ConsumeToken();
+ BalancedDelimiterTracker Parens(*this, tok::l_paren);
+ if (Parens.expectAndConsume())
+ return true;
+ SubRuleName = getIdentifier(Tok);
+ if (SubRuleName.empty()) {
+ diagnoseExpectedAttributeSubjectSubRule(*this, PrimaryRule, Name,
+ SubRuleLoc);
+ return true;
+ }
+ auto SubRuleOrNone = Rule.second(SubRuleName, /*IsUnless=*/true);
+ if (!SubRuleOrNone) {
+ std::string SubRuleUnlessName = "unless(" + SubRuleName.str() + ")";
+ diagnoseUnknownAttributeSubjectSubRule(*this, PrimaryRule, Name,
+ SubRuleUnlessName, SubRuleLoc);
+ return true;
+ }
+ SubRule = *SubRuleOrNone;
+ ConsumeToken();
+ if (Parens.consumeClose())
+ return true;
+ } else {
+ auto SubRuleOrNone = Rule.second(SubRuleName, /*IsUnless=*/false);
+ if (!SubRuleOrNone) {
+ diagnoseUnknownAttributeSubjectSubRule(*this, PrimaryRule, Name,
+ SubRuleName, Tok.getLocation());
+ return true;
+ }
+ SubRule = *SubRuleOrNone;
+ ConsumeToken();
+ }
+ SourceLocation RuleEndLoc = Tok.getLocation();
+ LastMatchRuleEndLoc = RuleEndLoc;
+ if (Parens.consumeClose())
+ return true;
+ if (!SubjectMatchRules
+ .insert(std::make_pair(SubRule, SourceRange(RuleLoc, RuleEndLoc)))
+ .second) {
+ Diag(RuleLoc, diag::err_pragma_attribute_duplicate_subject)
+ << attr::getSubjectMatchRuleSpelling(SubRule)
+ << FixItHint::CreateRemoval(SourceRange(
+ RuleLoc, Tok.is(tok::comma) ? Tok.getLocation() : RuleEndLoc));
+ continue;
+ }
+ } while (IsAny && TryConsumeToken(tok::comma));
+
+ if (IsAny)
+ if (AnyParens.consumeClose())
+ return true;
+
+ return false;
+}
+
+namespace {
+
+/// Describes the stage at which attribute subject rule parsing was interruped.
+enum class MissingAttributeSubjectRulesRecoveryPoint {
+ Comma,
+ ApplyTo,
+ Equals,
+ Any,
+ None,
+};
+
+MissingAttributeSubjectRulesRecoveryPoint
+getAttributeSubjectRulesRecoveryPointForToken(const Token &Tok) {
+ if (const auto *II = Tok.getIdentifierInfo()) {
+ if (II->isStr("apply_to"))
+ return MissingAttributeSubjectRulesRecoveryPoint::ApplyTo;
+ if (II->isStr("any"))
+ return MissingAttributeSubjectRulesRecoveryPoint::Any;
+ }
+ if (Tok.is(tok::equal))
+ return MissingAttributeSubjectRulesRecoveryPoint::Equals;
+ return MissingAttributeSubjectRulesRecoveryPoint::None;
+}
+
+/// Creates a diagnostic for the attribute subject rule parsing diagnostic that
+/// suggests the possible attribute subject rules in a fix-it together with
+/// any other missing tokens.
+DiagnosticBuilder createExpectedAttributeSubjectRulesTokenDiagnostic(
+ unsigned DiagID, AttributeList &Attribute,
+ MissingAttributeSubjectRulesRecoveryPoint Point, Parser &PRef) {
+ SourceLocation Loc = PRef.getEndOfPreviousToken();
+ if (Loc.isInvalid())
+ Loc = PRef.getCurToken().getLocation();
+ auto Diagnostic = PRef.Diag(Loc, DiagID);
+ std::string FixIt;
+ MissingAttributeSubjectRulesRecoveryPoint EndPoint =
+ getAttributeSubjectRulesRecoveryPointForToken(PRef.getCurToken());
+ if (Point == MissingAttributeSubjectRulesRecoveryPoint::Comma)
+ FixIt = ", ";
+ if (Point <= MissingAttributeSubjectRulesRecoveryPoint::ApplyTo &&
+ EndPoint > MissingAttributeSubjectRulesRecoveryPoint::ApplyTo)
+ FixIt += "apply_to";
+ if (Point <= MissingAttributeSubjectRulesRecoveryPoint::Equals &&
+ EndPoint > MissingAttributeSubjectRulesRecoveryPoint::Equals)
+ FixIt += " = ";
+ SourceRange FixItRange(Loc);
+ if (EndPoint == MissingAttributeSubjectRulesRecoveryPoint::None) {
+ // Gather the subject match rules that are supported by the attribute.
+ SmallVector<std::pair<attr::SubjectMatchRule, bool>, 4> SubjectMatchRuleSet;
+ Attribute.getMatchRules(PRef.getLangOpts(), SubjectMatchRuleSet);
+ if (SubjectMatchRuleSet.empty()) {
+ // FIXME: We can emit a "fix-it" with a subject list placeholder when
+ // placeholders will be supported by the fix-its.
+ return Diagnostic;
+ }
+ FixIt += "any(";
+ bool NeedsComma = false;
+ for (const auto &I : SubjectMatchRuleSet) {
+ // Ensure that the missing rule is reported in the fix-it only when it's
+ // supported in the current language mode.
+ if (!I.second)
+ continue;
+ if (NeedsComma)
+ FixIt += ", ";
+ else
+ NeedsComma = true;
+ FixIt += attr::getSubjectMatchRuleSpelling(I.first);
+ }
+ FixIt += ")";
+ // Check if we need to remove the range
+ PRef.SkipUntil(tok::eof, Parser::StopBeforeMatch);
+ FixItRange.setEnd(PRef.getCurToken().getLocation());
+ }
+ if (FixItRange.getBegin() == FixItRange.getEnd())
+ Diagnostic << FixItHint::CreateInsertion(FixItRange.getBegin(), FixIt);
+ else
+ Diagnostic << FixItHint::CreateReplacement(
+ CharSourceRange::getCharRange(FixItRange), FixIt);
+ return Diagnostic;
+}
+
+} // end anonymous namespace
+
+void Parser::HandlePragmaAttribute() {
+ assert(Tok.is(tok::annot_pragma_attribute) &&
+ "Expected #pragma attribute annotation token");
+ SourceLocation PragmaLoc = Tok.getLocation();
+ auto *Info = static_cast<PragmaAttributeInfo *>(Tok.getAnnotationValue());
+ if (Info->Action == PragmaAttributeInfo::Pop) {
+ ConsumeToken();
+ Actions.ActOnPragmaAttributePop(PragmaLoc);
+ return;
+ }
+ // Parse the actual attribute with its arguments.
+ assert(Info->Action == PragmaAttributeInfo::Push &&
+ "Unexpected #pragma attribute command");
+ PP.EnterTokenStream(Info->Tokens, /*DisableMacroExpansion=*/false);
+ ConsumeToken();
+
+ ParsedAttributes &Attrs = Info->Attributes;
+ Attrs.clearListOnly();
+
+ auto SkipToEnd = [this]() {
+ SkipUntil(tok::eof, StopBeforeMatch);
+ ConsumeToken();
+ };
+
+ if (Tok.is(tok::l_square) && NextToken().is(tok::l_square)) {
+ // Parse the CXX11 style attribute.
+ ParseCXX11AttributeSpecifier(Attrs);
+ } else if (Tok.is(tok::kw___attribute)) {
+ ConsumeToken();
+ if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
+ "attribute"))
+ return SkipToEnd();
+ if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "("))
+ return SkipToEnd();
+
+ if (Tok.isNot(tok::identifier)) {
+ Diag(Tok, diag::err_pragma_attribute_expected_attribute_name);
+ SkipToEnd();
+ return;
+ }
+ IdentifierInfo *AttrName = Tok.getIdentifierInfo();
+ SourceLocation AttrNameLoc = ConsumeToken();
+
+ if (Tok.isNot(tok::l_paren))
+ Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
+ AttributeList::AS_GNU);
+ else
+ ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, /*EndLoc=*/nullptr,
+ /*ScopeName=*/nullptr,
+ /*ScopeLoc=*/SourceLocation(),
+ AttributeList::AS_GNU,
+ /*Declarator=*/nullptr);
+
+ if (ExpectAndConsume(tok::r_paren))
+ return SkipToEnd();
+ if (ExpectAndConsume(tok::r_paren))
+ return SkipToEnd();
+ } else if (Tok.is(tok::kw___declspec)) {
+ ParseMicrosoftDeclSpecs(Attrs);
+ } else {
+ Diag(Tok, diag::err_pragma_attribute_expected_attribute_syntax);
+ if (Tok.getIdentifierInfo()) {
+ // If we suspect that this is an attribute suggest the use of
+ // '__attribute__'.
+ if (AttributeList::getKind(Tok.getIdentifierInfo(), /*ScopeName=*/nullptr,
+ AttributeList::AS_GNU) !=
+ AttributeList::UnknownAttribute) {
+ SourceLocation InsertStartLoc = Tok.getLocation();
+ ConsumeToken();
+ if (Tok.is(tok::l_paren)) {
+ ConsumeAnyToken();
+ SkipUntil(tok::r_paren, StopBeforeMatch);
+ if (Tok.isNot(tok::r_paren))
+ return SkipToEnd();
+ }
+ Diag(Tok, diag::note_pragma_attribute_use_attribute_kw)
+ << FixItHint::CreateInsertion(InsertStartLoc, "__attribute__((")
+ << FixItHint::CreateInsertion(Tok.getEndLoc(), "))");
+ }
+ }
+ SkipToEnd();
+ return;
+ }
+
+ if (!Attrs.getList() || Attrs.getList()->isInvalid()) {
+ SkipToEnd();
+ return;
+ }
+
+ // Ensure that we don't have more than one attribute.
+ if (Attrs.getList()->getNext()) {
+ SourceLocation Loc = Attrs.getList()->getNext()->getLoc();
+ Diag(Loc, diag::err_pragma_attribute_multiple_attributes);
+ SkipToEnd();
+ return;
+ }
+
+ if (!Attrs.getList()->isSupportedByPragmaAttribute()) {
+ Diag(PragmaLoc, diag::err_pragma_attribute_unsupported_attribute)
+ << Attrs.getList()->getName();
+ SkipToEnd();
+ return;
+ }
+ AttributeList &Attribute = *Attrs.getList();
+
+ // Parse the subject-list.
+ if (!TryConsumeToken(tok::comma)) {
+ createExpectedAttributeSubjectRulesTokenDiagnostic(
+ diag::err_expected, Attribute,
+ MissingAttributeSubjectRulesRecoveryPoint::Comma, *this)
+ << tok::comma;
+ SkipToEnd();
+ return;
+ }
+
+ if (Tok.isNot(tok::identifier)) {
+ createExpectedAttributeSubjectRulesTokenDiagnostic(
+ diag::err_pragma_attribute_invalid_subject_set_specifier, Attribute,
+ MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *this);
+ SkipToEnd();
+ return;
+ }
+ const IdentifierInfo *II = Tok.getIdentifierInfo();
+ if (!II->isStr("apply_to")) {
+ createExpectedAttributeSubjectRulesTokenDiagnostic(
+ diag::err_pragma_attribute_invalid_subject_set_specifier, Attribute,
+ MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *this);
+ SkipToEnd();
+ return;
+ }
+ ConsumeToken();
+
+ if (!TryConsumeToken(tok::equal)) {
+ createExpectedAttributeSubjectRulesTokenDiagnostic(
+ diag::err_expected, Attribute,
+ MissingAttributeSubjectRulesRecoveryPoint::Equals, *this)
+ << tok::equal;
+ SkipToEnd();
+ return;
+ }
+
+ attr::ParsedSubjectMatchRuleSet SubjectMatchRules;
+ SourceLocation AnyLoc, LastMatchRuleEndLoc;
+ if (ParsePragmaAttributeSubjectMatchRuleSet(SubjectMatchRules, AnyLoc,
+ LastMatchRuleEndLoc)) {
+ SkipToEnd();
+ return;
+ }
+
+ // Tokens following an ill-formed attribute will remain in the token stream
+ // and must be removed.
+ if (Tok.isNot(tok::eof)) {
+ Diag(Tok, diag::err_pragma_attribute_extra_tokens_after_attribute);
+ SkipToEnd();
+ return;
+ }
+
+ // Consume the eof terminator token.
+ ConsumeToken();
+
+ Actions.ActOnPragmaAttributePush(Attribute, PragmaLoc,
+ std::move(SubjectMatchRules));
+}
+
// #pragma GCC visibility comes in two variants:
// 'push' '(' [visibility] ')'
// 'pop'
@@ -2395,3 +2828,104 @@ void PragmaForceCUDAHostDeviceHandler::HandlePragma(
PP.Diag(FirstTok.getLocation(),
diag::warn_pragma_force_cuda_host_device_bad_arg);
}
+
+/// \brief Handle the #pragma clang attribute directive.
+///
+/// The syntax is:
+/// \code
+/// #pragma clang attribute push(attribute, subject-set)
+/// #pragma clang attribute pop
+/// \endcode
+///
+/// The subject-set clause defines the set of declarations which receive the
+/// attribute. Its exact syntax is described in the LanguageExtensions document
+/// in Clang's documentation.
+///
+/// This directive instructs the compiler to begin/finish applying the specified
+/// attribute to the set of attribute-specific declarations in the active range
+/// of the pragma.
+void PragmaAttributeHandler::HandlePragma(Preprocessor &PP,
+ PragmaIntroducerKind Introducer,
+ Token &FirstToken) {
+ Token Tok;
+ PP.Lex(Tok);
+ auto *Info = new (PP.getPreprocessorAllocator())
+ PragmaAttributeInfo(AttributesForPragmaAttribute);
+
+ // Parse the 'push' or 'pop'.
+ if (Tok.isNot(tok::identifier)) {
+ PP.Diag(Tok.getLocation(), diag::err_pragma_attribute_expected_push_pop);
+ return;
+ }
+ const auto *II = Tok.getIdentifierInfo();
+ if (II->isStr("push"))
+ Info->Action = PragmaAttributeInfo::Push;
+ else if (II->isStr("pop"))
+ Info->Action = PragmaAttributeInfo::Pop;
+ else {
+ PP.Diag(Tok.getLocation(), diag::err_pragma_attribute_invalid_argument)
+ << PP.getSpelling(Tok);
+ return;
+ }
+ PP.Lex(Tok);
+
+ // Parse the actual attribute.
+ if (Info->Action == PragmaAttributeInfo::Push) {
+ if (Tok.isNot(tok::l_paren)) {
+ PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
+ return;
+ }
+ PP.Lex(Tok);
+
+ // Lex the attribute tokens.
+ SmallVector<Token, 16> AttributeTokens;
+ int OpenParens = 1;
+ while (Tok.isNot(tok::eod)) {
+ if (Tok.is(tok::l_paren))
+ OpenParens++;
+ else if (Tok.is(tok::r_paren)) {
+ OpenParens--;
+ if (OpenParens == 0)
+ break;
+ }
+
+ AttributeTokens.push_back(Tok);
+ PP.Lex(Tok);
+ }
+
+ if (AttributeTokens.empty()) {
+ PP.Diag(Tok.getLocation(), diag::err_pragma_attribute_expected_attribute);
+ return;
+ }
+ if (Tok.isNot(tok::r_paren)) {
+ PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
+ return;
+ }
+ SourceLocation EndLoc = Tok.getLocation();
+ PP.Lex(Tok);
+
+ // Terminate the attribute for parsing.
+ Token EOFTok;
+ EOFTok.startToken();
+ EOFTok.setKind(tok::eof);
+ EOFTok.setLocation(EndLoc);
+ AttributeTokens.push_back(EOFTok);
+
+ Info->Tokens =
+ llvm::makeArrayRef(AttributeTokens).copy(PP.getPreprocessorAllocator());
+ }
+
+ if (Tok.isNot(tok::eod))
+ PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
+ << "clang attribute";
+
+ // Generate the annotated pragma token.
+ auto TokenArray = llvm::make_unique<Token[]>(1);
+ TokenArray[0].startToken();
+ TokenArray[0].setKind(tok::annot_pragma_attribute);
+ TokenArray[0].setLocation(FirstToken.getLocation());
+ TokenArray[0].setAnnotationEndLoc(FirstToken.getLocation());
+ TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
+ PP.EnterTokenStream(std::move(TokenArray), 1,
+ /*DisableMacroExpansion=*/false);
+}
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index eaff9fe8eedf..7d78046d0684 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -382,6 +382,10 @@ Retry:
case tok::annot_pragma_dump:
HandlePragmaDump();
return StmtEmpty();
+
+ case tok::annot_pragma_attribute:
+ HandlePragmaAttribute();
+ return StmtEmpty();
}
// If we reached this code, the statement must end in a semicolon.
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index aa8ed91d382f..edbfc636bc46 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -602,6 +602,10 @@ bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result) {
ConsumeToken();
return false;
+ case tok::annot_pragma_attribute:
+ HandlePragmaAttribute();
+ return false;
+
case tok::eof:
// Late template parsing can begin.
if (getLangOpts().DelayedTemplateParsing)
@@ -847,6 +851,10 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
default:
dont_know:
+ if (Tok.isEditorPlaceholder()) {
+ ConsumeToken();
+ return nullptr;
+ }
// We can't tell whether this is a function-definition or declaration yet.
return ParseDeclarationOrFunctionDefinition(attrs, DS);
}
@@ -1675,6 +1683,8 @@ bool Parser::TryAnnotateTypeOrScopeToken() {
return false;
}
}
+ if (Tok.isEditorPlaceholder())
+ return true;
Diag(Tok.getLocation(), diag::err_expected_qualified_after_typename);
return true;
diff --git a/lib/Sema/AttributeList.cpp b/lib/Sema/AttributeList.cpp
index 55e9601bf5e5..724db456785f 100644
--- a/lib/Sema/AttributeList.cpp
+++ b/lib/Sema/AttributeList.cpp
@@ -16,6 +16,7 @@
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
+#include "clang/Basic/AttrSubjectMatchRules.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Sema/SemaInternal.h"
@@ -160,12 +161,16 @@ struct ParsedAttrInfo {
unsigned IsType : 1;
unsigned IsStmt : 1;
unsigned IsKnownToGCC : 1;
+ unsigned IsSupportedByPragmaAttribute : 1;
bool (*DiagAppertainsToDecl)(Sema &S, const AttributeList &Attr,
const Decl *);
bool (*DiagLangOpts)(Sema &S, const AttributeList &Attr);
bool (*ExistsInTarget)(const TargetInfo &Target);
unsigned (*SpellingIndexToSemanticSpelling)(const AttributeList &Attr);
+ void (*GetPragmaAttributeMatchRules)(
+ llvm::SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &Rules,
+ const LangOptions &LangOpts);
};
namespace {
@@ -192,6 +197,18 @@ bool AttributeList::diagnoseAppertainsTo(Sema &S, const Decl *D) const {
return getInfo(*this).DiagAppertainsToDecl(S, *this, D);
}
+bool AttributeList::appliesToDecl(const Decl *D,
+ attr::SubjectMatchRule MatchRule) const {
+ return checkAttributeMatchRuleAppliesTo(D, MatchRule);
+}
+
+void AttributeList::getMatchRules(
+ const LangOptions &LangOpts,
+ SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &MatchRules)
+ const {
+ return getInfo(*this).GetPragmaAttributeMatchRules(MatchRules, LangOpts);
+}
+
bool AttributeList::diagnoseLangOpts(Sema &S) const {
return getInfo(*this).DiagLangOpts(S, *this);
}
@@ -216,6 +233,10 @@ bool AttributeList::isKnownToGCC() const {
return getInfo(*this).IsKnownToGCC;
}
+bool AttributeList::isSupportedByPragmaAttribute() const {
+ return getInfo(*this).IsSupportedByPragmaAttribute;
+}
+
unsigned AttributeList::getSemanticSpelling() const {
return getInfo(*this).SpellingIndexToSemanticSpelling(*this);
}
diff --git a/lib/Sema/JumpDiagnostics.cpp b/lib/Sema/JumpDiagnostics.cpp
index 899d3fa83cc3..865aea9e2284 100644
--- a/lib/Sema/JumpDiagnostics.cpp
+++ b/lib/Sema/JumpDiagnostics.cpp
@@ -287,6 +287,15 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S,
IndirectJumpTargets.push_back(cast<AddrLabelExpr>(S)->getLabel());
break;
+ case Stmt::ObjCForCollectionStmtClass: {
+ auto *CS = cast<ObjCForCollectionStmt>(S);
+ unsigned Diag = diag::note_protected_by_objc_fast_enumeration;
+ unsigned NewParentScope = Scopes.size();
+ Scopes.push_back(GotoScope(ParentScope, Diag, 0, S->getLocStart()));
+ BuildScopeInformation(CS->getBody(), NewParentScope);
+ return;
+ }
+
case Stmt::IndirectGotoStmtClass:
// "goto *&&lbl;" is a special case which we treat as equivalent
// to a normal goto. In addition, we don't calculate scope in the
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index 294b56059b33..950f04088822 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -71,42 +71,35 @@ void Sema::ActOnTranslationUnitScope(Scope *S) {
}
Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
- TranslationUnitKind TUKind,
- CodeCompleteConsumer *CodeCompleter)
- : ExternalSource(nullptr),
- isMultiplexExternalSource(false), FPFeatures(pp.getLangOpts()),
- LangOpts(pp.getLangOpts()), PP(pp), Context(ctxt), Consumer(consumer),
- Diags(PP.getDiagnostics()), SourceMgr(PP.getSourceManager()),
- CollectStats(false), CodeCompleter(CodeCompleter),
- CurContext(nullptr), OriginalLexicalContext(nullptr),
- MSStructPragmaOn(false),
- MSPointerToMemberRepresentationMethod(
- LangOpts.getMSPointerToMemberRepresentationMethod()),
- VtorDispStack(MSVtorDispAttr::Mode(LangOpts.VtorDispMode)),
- PackStack(0), DataSegStack(nullptr), BSSSegStack(nullptr),
- ConstSegStack(nullptr), CodeSegStack(nullptr), CurInitSeg(nullptr),
- VisContext(nullptr),
- IsBuildingRecoveryCallExpr(false),
- Cleanup{}, LateTemplateParser(nullptr),
- LateTemplateParserCleanup(nullptr), OpaqueParser(nullptr), IdResolver(pp),
- StdExperimentalNamespaceCache(nullptr), StdInitializerList(nullptr),
- CXXTypeInfoDecl(nullptr), MSVCGuidDecl(nullptr),
- NSNumberDecl(nullptr), NSValueDecl(nullptr),
- NSStringDecl(nullptr), StringWithUTF8StringMethod(nullptr),
- ValueWithBytesObjCTypeMethod(nullptr),
- NSArrayDecl(nullptr), ArrayWithObjectsMethod(nullptr),
- NSDictionaryDecl(nullptr), DictionaryWithObjectsMethod(nullptr),
- GlobalNewDeleteDeclared(false),
- TUKind(TUKind),
- NumSFINAEErrors(0),
- CachedFakeTopLevelModule(nullptr),
- AccessCheckingSFINAE(false), InNonInstantiationSFINAEContext(false),
- NonInstantiationEntries(0), ArgumentPackSubstitutionIndex(-1),
- CurrentInstantiationScope(nullptr), DisableTypoCorrection(false),
- TyposCorrected(0), AnalysisWarnings(*this), ThreadSafetyDeclCache(nullptr),
- VarDataSharingAttributesStack(nullptr), CurScope(nullptr),
- Ident_super(nullptr), Ident___float128(nullptr)
-{
+ TranslationUnitKind TUKind, CodeCompleteConsumer *CodeCompleter)
+ : ExternalSource(nullptr), isMultiplexExternalSource(false),
+ FPFeatures(pp.getLangOpts()), LangOpts(pp.getLangOpts()), PP(pp),
+ Context(ctxt), Consumer(consumer), Diags(PP.getDiagnostics()),
+ SourceMgr(PP.getSourceManager()), CollectStats(false),
+ CodeCompleter(CodeCompleter), CurContext(nullptr),
+ OriginalLexicalContext(nullptr), MSStructPragmaOn(false),
+ MSPointerToMemberRepresentationMethod(
+ LangOpts.getMSPointerToMemberRepresentationMethod()),
+ VtorDispStack(MSVtorDispAttr::Mode(LangOpts.VtorDispMode)), PackStack(0),
+ DataSegStack(nullptr), BSSSegStack(nullptr), ConstSegStack(nullptr),
+ CodeSegStack(nullptr), CurInitSeg(nullptr), VisContext(nullptr),
+ PragmaAttributeCurrentTargetDecl(nullptr),
+ IsBuildingRecoveryCallExpr(false), Cleanup{}, LateTemplateParser(nullptr),
+ LateTemplateParserCleanup(nullptr), OpaqueParser(nullptr), IdResolver(pp),
+ StdExperimentalNamespaceCache(nullptr), StdInitializerList(nullptr),
+ CXXTypeInfoDecl(nullptr), MSVCGuidDecl(nullptr), NSNumberDecl(nullptr),
+ NSValueDecl(nullptr), NSStringDecl(nullptr),
+ StringWithUTF8StringMethod(nullptr),
+ ValueWithBytesObjCTypeMethod(nullptr), NSArrayDecl(nullptr),
+ ArrayWithObjectsMethod(nullptr), NSDictionaryDecl(nullptr),
+ DictionaryWithObjectsMethod(nullptr), GlobalNewDeleteDeclared(false),
+ TUKind(TUKind), NumSFINAEErrors(0), CachedFakeTopLevelModule(nullptr),
+ AccessCheckingSFINAE(false), InNonInstantiationSFINAEContext(false),
+ NonInstantiationEntries(0), ArgumentPackSubstitutionIndex(-1),
+ CurrentInstantiationScope(nullptr), DisableTypoCorrection(false),
+ TyposCorrected(0), AnalysisWarnings(*this),
+ ThreadSafetyDeclCache(nullptr), VarDataSharingAttributesStack(nullptr),
+ CurScope(nullptr), Ident_super(nullptr), Ident___float128(nullptr) {
TUScope = nullptr;
LoadedExternalKnownNamespaces = false;
@@ -731,6 +724,8 @@ void Sema::ActOnEndOfTranslationUnit() {
CheckDelayedMemberExceptionSpecs();
}
+ DiagnoseUnterminatedPragmaAttribute();
+
// All delayed member exception specs should be checked or we end up accepting
// incompatible declarations.
// FIXME: This is wrong for TUKind == TU_Prefix. In that case, we need to
diff --git a/lib/Sema/SemaAttr.cpp b/lib/Sema/SemaAttr.cpp
index c6e3cc886316..76ca65373dda 100644
--- a/lib/Sema/SemaAttr.cpp
+++ b/lib/Sema/SemaAttr.cpp
@@ -368,6 +368,219 @@ void Sema::AddCFAuditedAttribute(Decl *D) {
D->addAttr(CFAuditedTransferAttr::CreateImplicit(Context, Loc));
}
+namespace {
+
+Optional<attr::SubjectMatchRule>
+getParentAttrMatcherRule(attr::SubjectMatchRule Rule) {
+ using namespace attr;
+ switch (Rule) {
+ default:
+ return None;
+#define ATTR_MATCH_RULE(Value, Spelling, IsAbstract)
+#define ATTR_MATCH_SUB_RULE(Value, Spelling, IsAbstract, Parent, IsNegated) \
+ case Value: \
+ return Parent;
+#include "clang/Basic/AttrSubMatchRulesList.inc"
+ }
+}
+
+bool isNegatedAttrMatcherSubRule(attr::SubjectMatchRule Rule) {
+ using namespace attr;
+ switch (Rule) {
+ default:
+ return false;
+#define ATTR_MATCH_RULE(Value, Spelling, IsAbstract)
+#define ATTR_MATCH_SUB_RULE(Value, Spelling, IsAbstract, Parent, IsNegated) \
+ case Value: \
+ return IsNegated;
+#include "clang/Basic/AttrSubMatchRulesList.inc"
+ }
+}
+
+CharSourceRange replacementRangeForListElement(const Sema &S,
+ SourceRange Range) {
+ // Make sure that the ',' is removed as well.
+ SourceLocation AfterCommaLoc = Lexer::findLocationAfterToken(
+ Range.getEnd(), tok::comma, S.getSourceManager(), S.getLangOpts(),
+ /*SkipTrailingWhitespaceAndNewLine=*/false);
+ if (AfterCommaLoc.isValid())
+ return CharSourceRange::getCharRange(Range.getBegin(), AfterCommaLoc);
+ else
+ return CharSourceRange::getTokenRange(Range);
+}
+
+std::string
+attrMatcherRuleListToString(ArrayRef<attr::SubjectMatchRule> Rules) {
+ std::string Result;
+ llvm::raw_string_ostream OS(Result);
+ for (const auto &I : llvm::enumerate(Rules)) {
+ if (I.index())
+ OS << (I.index() == Rules.size() - 1 ? ", and " : ", ");
+ OS << "'" << attr::getSubjectMatchRuleSpelling(I.value()) << "'";
+ }
+ return OS.str();
+}
+
+} // end anonymous namespace
+
+void Sema::ActOnPragmaAttributePush(AttributeList &Attribute,
+ SourceLocation PragmaLoc,
+ attr::ParsedSubjectMatchRuleSet Rules) {
+ SmallVector<attr::SubjectMatchRule, 4> SubjectMatchRules;
+ // Gather the subject match rules that are supported by the attribute.
+ SmallVector<std::pair<attr::SubjectMatchRule, bool>, 4>
+ StrictSubjectMatchRuleSet;
+ Attribute.getMatchRules(LangOpts, StrictSubjectMatchRuleSet);
+
+ // Figure out which subject matching rules are valid.
+ if (StrictSubjectMatchRuleSet.empty()) {
+ // Check for contradicting match rules. Contradicting match rules are
+ // either:
+ // - a top-level rule and one of its sub-rules. E.g. variable and
+ // variable(is_parameter).
+ // - a sub-rule and a sibling that's negated. E.g.
+ // variable(is_thread_local) and variable(unless(is_parameter))
+ llvm::SmallDenseMap<int, std::pair<int, SourceRange>, 2>
+ RulesToFirstSpecifiedNegatedSubRule;
+ for (const auto &Rule : Rules) {
+ attr::SubjectMatchRule MatchRule = attr::SubjectMatchRule(Rule.first);
+ Optional<attr::SubjectMatchRule> ParentRule =
+ getParentAttrMatcherRule(MatchRule);
+ if (!ParentRule)
+ continue;
+ auto It = Rules.find(*ParentRule);
+ if (It != Rules.end()) {
+ // A sub-rule contradicts a parent rule.
+ Diag(Rule.second.getBegin(),
+ diag::err_pragma_attribute_matcher_subrule_contradicts_rule)
+ << attr::getSubjectMatchRuleSpelling(MatchRule)
+ << attr::getSubjectMatchRuleSpelling(*ParentRule) << It->second
+ << FixItHint::CreateRemoval(
+ replacementRangeForListElement(*this, Rule.second));
+ // Keep going without removing this rule as it won't change the set of
+ // declarations that receive the attribute.
+ continue;
+ }
+ if (isNegatedAttrMatcherSubRule(MatchRule))
+ RulesToFirstSpecifiedNegatedSubRule.insert(
+ std::make_pair(*ParentRule, Rule));
+ }
+ bool IgnoreNegatedSubRules = false;
+ for (const auto &Rule : Rules) {
+ attr::SubjectMatchRule MatchRule = attr::SubjectMatchRule(Rule.first);
+ Optional<attr::SubjectMatchRule> ParentRule =
+ getParentAttrMatcherRule(MatchRule);
+ if (!ParentRule)
+ continue;
+ auto It = RulesToFirstSpecifiedNegatedSubRule.find(*ParentRule);
+ if (It != RulesToFirstSpecifiedNegatedSubRule.end() &&
+ It->second != Rule) {
+ // Negated sub-rule contradicts another sub-rule.
+ Diag(
+ It->second.second.getBegin(),
+ diag::
+ err_pragma_attribute_matcher_negated_subrule_contradicts_subrule)
+ << attr::getSubjectMatchRuleSpelling(
+ attr::SubjectMatchRule(It->second.first))
+ << attr::getSubjectMatchRuleSpelling(MatchRule) << Rule.second
+ << FixItHint::CreateRemoval(
+ replacementRangeForListElement(*this, It->second.second));
+ // Keep going but ignore all of the negated sub-rules.
+ IgnoreNegatedSubRules = true;
+ RulesToFirstSpecifiedNegatedSubRule.erase(It);
+ }
+ }
+
+ if (!IgnoreNegatedSubRules) {
+ for (const auto &Rule : Rules)
+ SubjectMatchRules.push_back(attr::SubjectMatchRule(Rule.first));
+ } else {
+ for (const auto &Rule : Rules) {
+ if (!isNegatedAttrMatcherSubRule(attr::SubjectMatchRule(Rule.first)))
+ SubjectMatchRules.push_back(attr::SubjectMatchRule(Rule.first));
+ }
+ }
+ Rules.clear();
+ } else {
+ for (const auto &Rule : StrictSubjectMatchRuleSet) {
+ if (Rules.erase(Rule.first)) {
+ // Add the rule to the set of attribute receivers only if it's supported
+ // in the current language mode.
+ if (Rule.second)
+ SubjectMatchRules.push_back(Rule.first);
+ }
+ }
+ }
+
+ if (!Rules.empty()) {
+ auto Diagnostic =
+ Diag(PragmaLoc, diag::err_pragma_attribute_invalid_matchers)
+ << Attribute.getName();
+ SmallVector<attr::SubjectMatchRule, 2> ExtraRules;
+ for (const auto &Rule : Rules) {
+ ExtraRules.push_back(attr::SubjectMatchRule(Rule.first));
+ Diagnostic << FixItHint::CreateRemoval(
+ replacementRangeForListElement(*this, Rule.second));
+ }
+ Diagnostic << attrMatcherRuleListToString(ExtraRules);
+ }
+
+ PragmaAttributeStack.push_back(
+ {PragmaLoc, &Attribute, std::move(SubjectMatchRules), /*IsUsed=*/false});
+}
+
+void Sema::ActOnPragmaAttributePop(SourceLocation PragmaLoc) {
+ if (PragmaAttributeStack.empty()) {
+ Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch);
+ return;
+ }
+ const PragmaAttributeEntry &Entry = PragmaAttributeStack.back();
+ if (!Entry.IsUsed) {
+ assert(Entry.Attribute && "Expected an attribute");
+ Diag(Entry.Attribute->getLoc(), diag::warn_pragma_attribute_unused)
+ << Entry.Attribute->getName();
+ Diag(PragmaLoc, diag::note_pragma_attribute_region_ends_here);
+ }
+ PragmaAttributeStack.pop_back();
+}
+
+void Sema::AddPragmaAttributes(Scope *S, Decl *D) {
+ if (PragmaAttributeStack.empty())
+ return;
+ for (auto &Entry : PragmaAttributeStack) {
+ const AttributeList *Attribute = Entry.Attribute;
+ assert(Attribute && "Expected an attribute");
+
+ // Ensure that the attribute can be applied to the given declaration.
+ bool Applies = false;
+ for (const auto &Rule : Entry.MatchRules) {
+ if (Attribute->appliesToDecl(D, Rule)) {
+ Applies = true;
+ break;
+ }
+ }
+ if (!Applies)
+ continue;
+ Entry.IsUsed = true;
+ assert(!Attribute->getNext() && "Expected just one attribute");
+ PragmaAttributeCurrentTargetDecl = D;
+ ProcessDeclAttributeList(S, D, Attribute);
+ PragmaAttributeCurrentTargetDecl = nullptr;
+ }
+}
+
+void Sema::PrintPragmaAttributeInstantiationPoint() {
+ assert(PragmaAttributeCurrentTargetDecl && "Expected an active declaration");
+ Diags.Report(PragmaAttributeCurrentTargetDecl->getLocStart(),
+ diag::note_pragma_attribute_applied_decl_here);
+}
+
+void Sema::DiagnoseUnterminatedPragmaAttribute() {
+ if (PragmaAttributeStack.empty())
+ return;
+ Diag(PragmaAttributeStack.back().Loc, diag::err_pragma_attribute_no_pop_eof);
+}
+
void Sema::ActOnPragmaOptimize(bool On, SourceLocation PragmaLoc) {
if(On)
OptimizeOffPragmaLocation = SourceLocation();
diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp
index 57471de78d3e..6da4d2a26191 100644
--- a/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/lib/Sema/SemaCXXScopeSpec.cpp
@@ -480,6 +480,8 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S, NestedNameSpecInfo &IdInfo,
bool ErrorRecoveryLookup,
bool *IsCorrectedToColon,
bool OnlyNamespace) {
+ if (IdInfo.Identifier->isEditorPlaceholder())
+ return true;
LookupResult Found(*this, IdInfo.Identifier, IdInfo.IdentifierLoc,
OnlyNamespace ? LookupNamespaceName
: LookupNestedNameSpecifierName);
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 81db0d3d00a7..45523b30ef22 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -1391,8 +1391,6 @@ bool Sema::CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall,
}
bool Sema::CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
- llvm::APSInt Result;
-
if (BuiltinID == ARM::BI__builtin_arm_ldrex ||
BuiltinID == ARM::BI__builtin_arm_ldaex ||
BuiltinID == ARM::BI__builtin_arm_strex ||
@@ -1439,8 +1437,6 @@ bool Sema::CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
bool Sema::CheckAArch64BuiltinFunctionCall(unsigned BuiltinID,
CallExpr *TheCall) {
- llvm::APSInt Result;
-
if (BuiltinID == AArch64::BI__builtin_arm_ldrex ||
BuiltinID == AArch64::BI__builtin_arm_ldaex ||
BuiltinID == AArch64::BI__builtin_arm_strex ||
diff --git a/lib/Sema/SemaCoroutine.cpp b/lib/Sema/SemaCoroutine.cpp
index 4a55e51495a8..c709a1a723d0 100644
--- a/lib/Sema/SemaCoroutine.cpp
+++ b/lib/Sema/SemaCoroutine.cpp
@@ -454,7 +454,7 @@ static bool actOnCoroutineBodyStart(Sema &S, Scope *SC, SourceLocation KWLoc,
/*IsImplicit*/ true);
Suspend = S.ActOnFinishFullExpr(Suspend.get());
if (Suspend.isInvalid()) {
- S.Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
+ S.Diag(Loc, diag::note_coroutine_promise_suspend_implicitly_required)
<< ((Name == "initial_suspend") ? 0 : 1);
S.Diag(KWLoc, diag::note_declared_coroutine_here) << Keyword;
return StmtError();
@@ -660,6 +660,39 @@ StmtResult Sema::BuildCoreturnStmt(SourceLocation Loc, Expr *E,
return Res;
}
+/// Look up the std::nothrow object.
+static Expr *buildStdNoThrowDeclRef(Sema &S, SourceLocation Loc) {
+ NamespaceDecl *Std = S.getStdNamespace();
+ assert(Std && "Should already be diagnosed");
+
+ LookupResult Result(S, &S.PP.getIdentifierTable().get("nothrow"), Loc,
+ Sema::LookupOrdinaryName);
+ if (!S.LookupQualifiedName(Result, Std)) {
+ // FIXME: <experimental/coroutine> should have been included already.
+ // If we require it to include <new> then this diagnostic is no longer
+ // needed.
+ S.Diag(Loc, diag::err_implicit_coroutine_std_nothrow_type_not_found);
+ return nullptr;
+ }
+
+ // FIXME: Mark the variable as ODR used. This currently does not work
+ // likely due to the scope at in which this function is called.
+ auto *VD = Result.getAsSingle<VarDecl>();
+ if (!VD) {
+ Result.suppressDiagnostics();
+ // We found something weird. Complain about the first thing we found.
+ NamedDecl *Found = *Result.begin();
+ S.Diag(Found->getLocation(), diag::err_malformed_std_nothrow);
+ return nullptr;
+ }
+
+ ExprResult DR = S.BuildDeclRefExpr(VD, VD->getType(), VK_LValue, Loc);
+ if (DR.isInvalid())
+ return nullptr;
+
+ return DR.get();
+}
+
// Find an appropriate delete for the promise.
static FunctionDecl *findDeleteForPromise(Sema &S, SourceLocation Loc,
QualType PromiseType) {
@@ -847,23 +880,53 @@ bool CoroutineStmtBuilder::makeNewAndDeleteExpr() {
if (S.RequireCompleteType(Loc, PromiseType, diag::err_incomplete_type))
return false;
- // FIXME: Add nothrow_t placement arg for global alloc
- // if ReturnStmtOnAllocFailure != nullptr.
+ const bool RequiresNoThrowAlloc = ReturnStmtOnAllocFailure != nullptr;
+
// FIXME: Add support for stateful allocators.
FunctionDecl *OperatorNew = nullptr;
FunctionDecl *OperatorDelete = nullptr;
FunctionDecl *UnusedResult = nullptr;
bool PassAlignment = false;
+ SmallVector<Expr *, 1> PlacementArgs;
S.FindAllocationFunctions(Loc, SourceRange(),
/*UseGlobal*/ false, PromiseType,
- /*isArray*/ false, PassAlignment,
- /*PlacementArgs*/ None, OperatorNew, UnusedResult);
+ /*isArray*/ false, PassAlignment, PlacementArgs,
+ OperatorNew, UnusedResult);
+
+ bool IsGlobalOverload =
+ OperatorNew && !isa<CXXRecordDecl>(OperatorNew->getDeclContext());
+ // If we didn't find a class-local new declaration and non-throwing new
+ // was is required then we need to lookup the non-throwing global operator
+ // instead.
+ if (RequiresNoThrowAlloc && (!OperatorNew || IsGlobalOverload)) {
+ auto *StdNoThrow = buildStdNoThrowDeclRef(S, Loc);
+ if (!StdNoThrow)
+ return false;
+ PlacementArgs = {StdNoThrow};
+ OperatorNew = nullptr;
+ S.FindAllocationFunctions(Loc, SourceRange(),
+ /*UseGlobal*/ true, PromiseType,
+ /*isArray*/ false, PassAlignment, PlacementArgs,
+ OperatorNew, UnusedResult);
+ }
- OperatorDelete = findDeleteForPromise(S, Loc, PromiseType);
+ assert(OperatorNew && "expected definition of operator new to be found");
- if (!OperatorDelete || !OperatorNew)
+ if (RequiresNoThrowAlloc) {
+ const auto *FT = OperatorNew->getType()->getAs<FunctionProtoType>();
+ if (!FT->isNothrow(S.Context, /*ResultIfDependent*/ false)) {
+ S.Diag(OperatorNew->getLocation(),
+ diag::err_coroutine_promise_new_requires_nothrow)
+ << OperatorNew;
+ S.Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
+ << OperatorNew;
+ return false;
+ }
+ }
+
+ if ((OperatorDelete = findDeleteForPromise(S, Loc, PromiseType)) == nullptr)
return false;
Expr *FramePtr =
@@ -879,8 +942,13 @@ bool CoroutineStmtBuilder::makeNewAndDeleteExpr() {
if (NewRef.isInvalid())
return false;
+ SmallVector<Expr *, 2> NewArgs(1, FrameSize);
+ for (auto Arg : PlacementArgs)
+ NewArgs.push_back(Arg);
+
ExprResult NewExpr =
- S.ActOnCallExpr(S.getCurScope(), NewRef.get(), Loc, FrameSize, Loc);
+ S.ActOnCallExpr(S.getCurScope(), NewRef.get(), Loc, NewArgs, Loc);
+ NewExpr = S.ActOnFinishFullExpr(NewExpr.get());
if (NewExpr.isInvalid())
return false;
@@ -906,6 +974,7 @@ bool CoroutineStmtBuilder::makeNewAndDeleteExpr() {
ExprResult DeleteExpr =
S.ActOnCallExpr(S.getCurScope(), DeleteRef.get(), Loc, DeleteArgs, Loc);
+ DeleteExpr = S.ActOnFinishFullExpr(DeleteExpr.get());
if (DeleteExpr.isInvalid())
return false;
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index c6a0b0101d37..f3ffcf5d696c 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -628,6 +628,9 @@ void Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II,
CXXScopeSpec *SS,
ParsedType &SuggestedType,
bool AllowClassTemplates) {
+ // Don't report typename errors for editor placeholders.
+ if (II->isEditorPlaceholder())
+ return;
// We don't have anything to suggest (yet).
SuggestedType = nullptr;
@@ -13674,6 +13677,7 @@ CreateNewDecl:
if (Attr)
ProcessDeclAttributeList(S, New, Attr);
+ AddPragmaAttributes(S, New);
// If this has an identifier, add it to the scope stack.
if (TUK == TUK_Friend) {
@@ -15185,6 +15189,7 @@ Decl *Sema::ActOnEnumConstant(Scope *S, Decl *theEnumDecl, Decl *lastEnumConst,
// Process attributes.
if (Attr) ProcessDeclAttributeList(S, New, Attr);
+ AddPragmaAttributes(S, New);
// Register this decl in the current scope stack.
New->setAccess(TheEnumDecl->getAccess());
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index a1ba9de368db..027b3fe0e782 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -2398,10 +2398,8 @@ static void handleAvailabilityAttr(Sema &S, Decl *D,
<< Platform->Ident;
NamedDecl *ND = dyn_cast<NamedDecl>(D);
- if (!ND) {
- S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
+ if (!ND) // We warned about this already, so just return.
return;
- }
AvailabilityChange Introduced = Attr.getAvailabilityIntroduced();
AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated();
@@ -2511,12 +2509,6 @@ static void handleExternalSourceSymbolAttr(Sema &S, Decl *D,
assert(checkAttributeAtMostNumArgs(S, Attr, 3) &&
"Invalid number of arguments in an external_source_symbol attribute");
- if (!isa<NamedDecl>(D)) {
- S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
- << Attr.getName() << ExpectedNamedDecl;
- return;
- }
-
StringRef Language;
if (const auto *SE = dyn_cast_or_null<StringLiteral>(Attr.getArgAsExpr(0)))
Language = SE->getString();
@@ -5765,18 +5757,21 @@ static void handleOpenCLNoSVMAttr(Sema &S, Decl *D, const AttributeList &Attr) {
static bool handleCommonAttributeFeatures(Sema &S, Scope *scope, Decl *D,
const AttributeList &Attr) {
// Several attributes carry different semantics than the parsing requires, so
- // those are opted out of the common handling.
+ // those are opted out of the common argument checks.
//
// We also bail on unknown and ignored attributes because those are handled
// as part of the target-specific handling logic.
- if (Attr.hasCustomParsing() ||
- Attr.getKind() == AttributeList::UnknownAttribute)
+ if (Attr.getKind() == AttributeList::UnknownAttribute)
return false;
-
// Check whether the attribute requires specific language extensions to be
// enabled.
if (!Attr.diagnoseLangOpts(S))
return true;
+ // Check whether the attribute appertains to the given subject.
+ if (!Attr.diagnoseAppertainsTo(S, D))
+ return true;
+ if (Attr.hasCustomParsing())
+ return false;
if (Attr.getMinArgs() == Attr.getMaxArgs()) {
// If there are no optional arguments, then checking for the argument count
@@ -5793,10 +5788,6 @@ static bool handleCommonAttributeFeatures(Sema &S, Scope *scope, Decl *D,
return true;
}
- // Check whether the attribute appertains to the given subject.
- if (!Attr.diagnoseAppertainsTo(S, D))
- return true;
-
return false;
}
@@ -6676,6 +6667,9 @@ void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) {
// Finally, apply any attributes on the decl itself.
if (const AttributeList *Attrs = PD.getAttributes())
ProcessDeclAttributeList(S, D, Attrs);
+
+ // Apply additional attributes specified by '#pragma clang attribute'.
+ AddPragmaAttributes(S, D);
}
/// Is the given declaration allowed to use a forbidden type?
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index fd3f266c9a08..b543a731641f 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -8445,6 +8445,7 @@ Decl *Sema::ActOnStartNamespaceDef(Scope *NamespcScope,
Namespc->setInvalidDecl();
ProcessDeclAttributeList(DeclRegionScope, Namespc, AttrList);
+ AddPragmaAttributes(DeclRegionScope, Namespc);
// FIXME: Should we be merging attributes?
if (const VisibilityAttr *Attr = Namespc->getAttr<VisibilityAttr>())
@@ -9931,6 +9932,7 @@ Decl *Sema::ActOnAliasDeclaration(Scope *S,
NewTD->setInvalidDecl();
ProcessDeclAttributeList(S, NewTD, AttrList);
+ AddPragmaAttributes(S, NewTD);
CheckTypedefForVariablyModifiedType(S, NewTD);
Invalid |= NewTD->isInvalidDecl();
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index e50f8b206779..4f51cd399c0c 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -993,6 +993,7 @@ ActOnStartClassInterface(Scope *S, SourceLocation AtInterfaceLoc,
if (AttrList)
ProcessDeclAttributeList(TUScope, IDecl, AttrList);
+ AddPragmaAttributes(TUScope, IDecl);
PushOnScopeChains(IDecl, TUScope);
// Start the definition of this class. If we're in a redefinition case, there
@@ -1176,7 +1177,8 @@ Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc,
if (AttrList)
ProcessDeclAttributeList(TUScope, PDecl, AttrList);
-
+ AddPragmaAttributes(TUScope, PDecl);
+
// Merge attributes from previous declarations.
if (PrevDecl)
mergeDeclAttributes(PDecl, PrevDecl);
@@ -1706,7 +1708,8 @@ Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
if (attrList)
ProcessDeclAttributeList(TUScope, PDecl, attrList);
-
+ AddPragmaAttributes(TUScope, PDecl);
+
if (PrevDecl)
mergeDeclAttributes(PDecl, PrevDecl);
@@ -1805,6 +1808,7 @@ ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
if (AttrList)
ProcessDeclAttributeList(TUScope, CDecl, AttrList);
+ AddPragmaAttributes(TUScope, CDecl);
CheckObjCDeclScope(CDecl);
return ActOnObjCContainerStartDefinition(CDecl);
@@ -1954,6 +1958,7 @@ Decl *Sema::ActOnStartClassImplementation(
ClassName, /*typeParamList=*/nullptr,
/*PrevDecl=*/nullptr, ClassLoc,
true);
+ AddPragmaAttributes(TUScope, IDecl);
IDecl->startDefinition();
if (SDecl) {
IDecl->setSuperClass(Context.getTrivialTypeSourceInfo(
@@ -3043,7 +3048,7 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
ClassName, TypeParams, PrevIDecl,
IdentLocs[i]);
IDecl->setAtEndRange(IdentLocs[i]);
-
+
PushOnScopeChains(IDecl, TUScope);
CheckObjCDeclScope(IDecl);
DeclsInGroup.push_back(IDecl);
@@ -4399,6 +4404,7 @@ Decl *Sema::ActOnMethodDeclaration(
// Apply the attributes to the parameter.
ProcessDeclAttributeList(TUScope, Param, ArgInfo[i].ArgAttrs);
+ AddPragmaAttributes(TUScope, Param);
if (Param->hasAttr<BlocksAttr>()) {
Diag(Param->getLocation(), diag::err_block_on_nonlocal);
@@ -4429,6 +4435,7 @@ Decl *Sema::ActOnMethodDeclaration(
if (AttrList)
ProcessDeclAttributeList(TUScope, ObjCMethod, AttrList);
+ AddPragmaAttributes(TUScope, ObjCMethod);
// Add the method now.
const ObjCMethodDecl *PrevMethod = nullptr;
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index bb174521c72c..5a56f7093777 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -2129,6 +2129,12 @@ Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS,
IdentifierInfo *II = Name.getAsIdentifierInfo();
SourceLocation NameLoc = NameInfo.getLoc();
+ if (II && II->isEditorPlaceholder()) {
+ // FIXME: When typed placeholders are supported we can create a typed
+ // placeholder expression node.
+ return ExprError();
+ }
+
// C++ [temp.dep.expr]p3:
// An id-expression is type-dependent if it contains:
// -- an identifier that was declared with a dependent type,
diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp
index 616ab05eaec8..d7a6d2e5885e 100644
--- a/lib/Sema/SemaOpenMP.cpp
+++ b/lib/Sema/SemaOpenMP.cpp
@@ -4068,7 +4068,7 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
// Build variables passed into runtime, necessary for worksharing directives.
- ExprResult LB, UB, IL, ST, EUB, PrevLB, PrevUB;
+ ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
isOpenMPDistributeDirective(DKind)) {
// Lower bound variable, initialized with zero.
@@ -4116,8 +4116,32 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
// enclosing region. E.g. in 'distribute parallel for' the bounds obtained
// by scheduling 'distribute' have to be passed to the schedule of 'for'.
if (isOpenMPLoopBoundSharingDirective(DKind)) {
- auto *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
+ // Lower bound variable, initialized with zero.
+ VarDecl *CombLBDecl =
+ buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
+ CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
+ SemaRef.AddInitializerToDecl(
+ CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
+ /*DirectInit*/ false);
+
+ // Upper bound variable, initialized with last iteration number.
+ VarDecl *CombUBDecl =
+ buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
+ CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
+ SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
+ /*DirectInit*/ false);
+
+ ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
+ CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
+ ExprResult CombCondOp =
+ SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
+ LastIteration.get(), CombUB.get());
+ CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
+ CombCondOp.get());
+ CombEUB = SemaRef.ActOnFinishFullExpr(CombEUB.get());
+
+ auto *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
// We expect to have at least 2 more parameters than the 'parallel'
// directive does - the lower and upper bounds of the previous schedule.
assert(CD->getNumParams() >= 4 &&
@@ -4139,7 +4163,7 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
// Build the iteration variable and its initialization before loop.
ExprResult IV;
- ExprResult Init;
+ ExprResult Init, CombInit;
{
VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
@@ -4150,6 +4174,18 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
: SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
Init = SemaRef.ActOnFinishFullExpr(Init.get());
+
+ if (isOpenMPLoopBoundSharingDirective(DKind)) {
+ Expr *CombRHS =
+ (isOpenMPWorksharingDirective(DKind) ||
+ isOpenMPTaskLoopDirective(DKind) ||
+ isOpenMPDistributeDirective(DKind))
+ ? CombLB.get()
+ : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
+ CombInit =
+ SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
+ CombInit = SemaRef.ActOnFinishFullExpr(CombInit.get());
+ }
}
// Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops.
@@ -4160,7 +4196,11 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get())
: SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
NumIterations.get());
-
+ ExprResult CombCond;
+ if (isOpenMPLoopBoundSharingDirective(DKind)) {
+ CombCond =
+ SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), CombUB.get());
+ }
// Loop increment (IV = IV + 1)
SourceLocation IncLoc;
ExprResult Inc =
@@ -4175,7 +4215,9 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
// Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
// Used for directives with static scheduling.
- ExprResult NextLB, NextUB;
+ // In combined construct, add combined version that use CombLB and CombUB
+ // base variables for the update
+ ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
isOpenMPDistributeDirective(DKind)) {
// LB + ST
@@ -4198,9 +4240,32 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get());
if (!NextUB.isUsable())
return 0;
- }
-
- // Create: increment expression for distribute loop when combined in a same
+ if (isOpenMPLoopBoundSharingDirective(DKind)) {
+ CombNextLB =
+ SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
+ if (!NextLB.isUsable())
+ return 0;
+ // LB = LB + ST
+ CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
+ CombNextLB.get());
+ CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get());
+ if (!CombNextLB.isUsable())
+ return 0;
+ // UB + ST
+ CombNextUB =
+ SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
+ if (!CombNextUB.isUsable())
+ return 0;
+ // UB = UB + ST
+ CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
+ CombNextUB.get());
+ CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get());
+ if (!CombNextUB.isUsable())
+ return 0;
+ }
+ }
+
+ // Create increment expression for distribute loop when combined in a same
// directive with for as IV = IV + ST; ensure upper bound expression based
// on PrevUB instead of NumIterations - used to implement 'for' when found
// in combination with 'distribute', like in 'distribute parallel for'
@@ -4346,6 +4411,13 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
Built.PrevUB = PrevUB.get();
Built.DistInc = DistInc.get();
Built.PrevEUB = PrevEUB.get();
+ Built.DistCombinedFields.LB = CombLB.get();
+ Built.DistCombinedFields.UB = CombUB.get();
+ Built.DistCombinedFields.EUB = CombEUB.get();
+ Built.DistCombinedFields.Init = CombInit.get();
+ Built.DistCombinedFields.Cond = CombCond.get();
+ Built.DistCombinedFields.NLB = CombNextLB.get();
+ Built.DistCombinedFields.NUB = CombNextUB.get();
Expr *CounterVal = SemaRef.DefaultLvalueConversion(IV.get()).get();
// Fill data for doacross depend clauses.
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 9be1c56f0622..9ffc23b5adba 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -1783,6 +1783,7 @@ StmtResult
Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc,
Stmt *First, Expr *collection,
SourceLocation RParenLoc) {
+ getCurFunction()->setHasBranchProtectedScope();
ExprResult CollectionExprResult =
CheckObjCForCollectionOperand(ForLoc, collection);
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index f522e76b0673..61b4df40964c 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -1636,11 +1636,22 @@ private:
transformFunctionTypeParam(ParmVarDecl *OldParam,
MultiLevelTemplateArgumentList &Args) {
TypeSourceInfo *OldDI = OldParam->getTypeSourceInfo();
- TypeSourceInfo *NewDI =
- Args.getNumLevels()
- ? SemaRef.SubstType(OldDI, Args, OldParam->getLocation(),
- OldParam->getDeclName())
- : OldDI;
+ TypeSourceInfo *NewDI;
+ if (!Args.getNumLevels())
+ NewDI = OldDI;
+ else if (auto PackTL = OldDI->getTypeLoc().getAs<PackExpansionTypeLoc>()) {
+ // Expand out the one and only element in each inner pack.
+ Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, 0);
+ NewDI =
+ SemaRef.SubstType(PackTL.getPatternLoc(), Args,
+ OldParam->getLocation(), OldParam->getDeclName());
+ if (!NewDI) return nullptr;
+ NewDI =
+ SemaRef.CheckPackExpansion(NewDI, PackTL.getEllipsisLoc(),
+ PackTL.getTypePtr()->getNumExpansions());
+ } else
+ NewDI = SemaRef.SubstType(OldDI, Args, OldParam->getLocation(),
+ OldParam->getDeclName());
if (!NewDI)
return nullptr;
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index edd6edfce9dc..2d44489023ef 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -2605,10 +2605,11 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation,
== TSK_ExplicitSpecialization)
continue;
- if (Context.getTargetInfo().getCXXABI().isMicrosoft() &&
+ if ((Context.getTargetInfo().getCXXABI().isMicrosoft() ||
+ Context.getTargetInfo().getTriple().isWindowsItaniumEnvironment()) &&
TSK == TSK_ExplicitInstantiationDeclaration) {
- // In MSVC mode, explicit instantiation decl of the outer class doesn't
- // affect the inner class.
+ // In MSVC and Windows Itanium mode, explicit instantiation decl of the
+ // outer class doesn't affect the inner class.
continue;
}
diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp
index a12fb8cf95a0..3d314a85ff17 100644
--- a/lib/Serialization/ASTReaderStmt.cpp
+++ b/lib/Serialization/ASTReaderStmt.cpp
@@ -2578,6 +2578,13 @@ void ASTStmtReader::VisitOMPLoopDirective(OMPLoopDirective *D) {
D->setPrevUpperBoundVariable(Record.readSubExpr());
D->setDistInc(Record.readSubExpr());
D->setPrevEnsureUpperBound(Record.readSubExpr());
+ D->setCombinedLowerBoundVariable(Record.readSubExpr());
+ D->setCombinedUpperBoundVariable(Record.readSubExpr());
+ D->setCombinedEnsureUpperBound(Record.readSubExpr());
+ D->setCombinedInit(Record.readSubExpr());
+ D->setCombinedCond(Record.readSubExpr());
+ D->setCombinedNextLowerBound(Record.readSubExpr());
+ D->setCombinedNextUpperBound(Record.readSubExpr());
}
SmallVector<Expr *, 4> Sub;
unsigned CollapsedNum = D->getCollapsedNumber();
diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp
index 1a2edac65886..90a732e575e2 100644
--- a/lib/Serialization/ASTWriterStmt.cpp
+++ b/lib/Serialization/ASTWriterStmt.cpp
@@ -2248,6 +2248,13 @@ void ASTStmtWriter::VisitOMPLoopDirective(OMPLoopDirective *D) {
Record.AddStmt(D->getPrevUpperBoundVariable());
Record.AddStmt(D->getDistInc());
Record.AddStmt(D->getPrevEnsureUpperBound());
+ Record.AddStmt(D->getCombinedLowerBoundVariable());
+ Record.AddStmt(D->getCombinedUpperBoundVariable());
+ Record.AddStmt(D->getCombinedEnsureUpperBound());
+ Record.AddStmt(D->getCombinedInit());
+ Record.AddStmt(D->getCombinedCond());
+ Record.AddStmt(D->getCombinedNextLowerBound());
+ Record.AddStmt(D->getCombinedNextUpperBound());
}
for (auto I : D->counters()) {
Record.AddStmt(I);