summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpatrick <patrick@openbsd.org>2020-08-09 15:51:07 +0000
committerpatrick <patrick@openbsd.org>2020-08-09 15:51:07 +0000
commit389bb291c0c8961ca40ac7a2636e1ca69ca7653c (patch)
treee027d0b3ed5ed27fe08d1bcaa20e3c191232a53b
parentImport LLVM 10.0.1 including clang, lld and lldb. (diff)
downloadwireguard-openbsd-389bb291c0c8961ca40ac7a2636e1ca69ca7653c.tar.xz
wireguard-openbsd-389bb291c0c8961ca40ac7a2636e1ca69ca7653c.zip
Import LLVM 10.0.1 including clang, lld and lldb.
-rw-r--r--gnu/llvm/clang/CMakeLists.txt1
-rw-r--r--gnu/llvm/clang/docs/ClangCommandLineReference.rst4
-rw-r--r--gnu/llvm/clang/docs/ReleaseNotes.rst7
-rw-r--r--gnu/llvm/clang/include/clang/AST/DeclBase.h9
-rw-r--r--gnu/llvm/clang/include/clang/Basic/Attr.td2
-rw-r--r--gnu/llvm/clang/include/clang/Driver/Options.td8
-rw-r--r--gnu/llvm/clang/lib/AST/DeclBase.cpp5
-rw-r--r--gnu/llvm/clang/lib/AST/ExprConstant.cpp23
-rw-r--r--gnu/llvm/clang/lib/AST/RawCommentList.cpp2
-rw-r--r--gnu/llvm/clang/lib/Basic/CMakeLists.txt4
-rw-r--r--gnu/llvm/clang/lib/Basic/Targets/PPC.h3
-rw-r--r--gnu/llvm/clang/lib/CodeGen/CGVTables.cpp5
-rw-r--r--gnu/llvm/clang/lib/CodeGen/CMakeLists.txt3
-rw-r--r--gnu/llvm/clang/lib/CodeGen/CodeGenModule.cpp11
-rw-r--r--gnu/llvm/clang/lib/CodeGen/TargetInfo.cpp3
-rw-r--r--gnu/llvm/clang/lib/Driver/SanitizerArgs.cpp3
-rw-r--r--gnu/llvm/clang/lib/Driver/ToolChain.cpp9
-rw-r--r--gnu/llvm/clang/lib/Driver/ToolChains/Darwin.cpp1
-rw-r--r--gnu/llvm/clang/lib/Driver/ToolChains/Gnu.cpp20
-rw-r--r--gnu/llvm/clang/lib/Driver/ToolChains/Gnu.h6
-rw-r--r--gnu/llvm/clang/lib/Driver/ToolChains/Hurd.cpp8
-rw-r--r--gnu/llvm/clang/lib/Driver/ToolChains/Hurd.h6
-rw-r--r--gnu/llvm/clang/lib/Driver/ToolChains/Linux.cpp5
-rw-r--r--gnu/llvm/clang/lib/Driver/ToolChains/Linux.h4
-rw-r--r--gnu/llvm/clang/lib/Format/TokenAnnotator.cpp52
-rwxr-xr-xgnu/llvm/clang/lib/Sema/SemaTemplate.cpp8
-rw-r--r--gnu/llvm/clang/lib/Sema/SemaTemplateInstantiate.cpp2
-rwxr-xr-xgnu/llvm/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp2
-rw-r--r--gnu/llvm/clang/lib/Sema/TreeTransform.h98
-rw-r--r--gnu/llvm/clang/lib/Tooling/Syntax/Tokens.cpp320
-rw-r--r--gnu/llvm/clang/tools/libclang/CMakeLists.txt1
-rw-r--r--gnu/llvm/clang/unittests/Format/FormatTest.cpp60
-rw-r--r--gnu/llvm/clang/unittests/Tooling/Syntax/TokensTest.cpp25
-rw-r--r--gnu/llvm/clang/utils/TableGen/ClangAttrEmitter.cpp3
34 files changed, 437 insertions, 286 deletions
diff --git a/gnu/llvm/clang/CMakeLists.txt b/gnu/llvm/clang/CMakeLists.txt
index 781c3eb7f2f..dc1413f4b59 100644
--- a/gnu/llvm/clang/CMakeLists.txt
+++ b/gnu/llvm/clang/CMakeLists.txt
@@ -864,6 +864,7 @@ add_subdirectory(utils/hmaptool)
if(CLANG_BUILT_STANDALONE)
llvm_distribution_add_targets()
+ process_llvm_pass_plugins()
endif()
configure_file(
diff --git a/gnu/llvm/clang/docs/ClangCommandLineReference.rst b/gnu/llvm/clang/docs/ClangCommandLineReference.rst
index 10c14db1b89..0292e160176 100644
--- a/gnu/llvm/clang/docs/ClangCommandLineReference.rst
+++ b/gnu/llvm/clang/docs/ClangCommandLineReference.rst
@@ -2577,6 +2577,10 @@ Use Intel MCU ABI
Generate branches with extended addressability, usually via indirect jumps.
+.. option:: -mlvi-cfi, -mno-lvi-cfi
+
+Enable only control-flow mitigations for Load Value Injection (LVI)
+
.. option:: -mmacosx-version-min=<arg>, -mmacos-version-min=<arg>
Set Mac OS X deployment target
diff --git a/gnu/llvm/clang/docs/ReleaseNotes.rst b/gnu/llvm/clang/docs/ReleaseNotes.rst
index a100d0a76b4..4939230a064 100644
--- a/gnu/llvm/clang/docs/ReleaseNotes.rst
+++ b/gnu/llvm/clang/docs/ReleaseNotes.rst
@@ -184,6 +184,13 @@ New Compiler Flags
- ``-mbranches-within-32B-boundaries`` is added as an x86 assembler mitigation
for Intel's Jump Condition Code Erratum.
+- -ffp-exception-behavior={ignore,maytrap,strict} allows the user to specify
+ the floating-point exception behavior. The default setting is ``ignore``.
+
+- -ffp-model={precise,strict,fast} provides the user an umbrella option to
+ simplify access to the many single purpose floating point options. The default
+ setting is ``precise``.
+
Deprecated Compiler Flags
-------------------------
diff --git a/gnu/llvm/clang/include/clang/AST/DeclBase.h b/gnu/llvm/clang/include/clang/AST/DeclBase.h
index 91c372585b0..fbcf255add1 100644
--- a/gnu/llvm/clang/include/clang/AST/DeclBase.h
+++ b/gnu/llvm/clang/include/clang/AST/DeclBase.h
@@ -856,14 +856,15 @@ public:
return getParentFunctionOrMethod() == nullptr;
}
- /// Returns true if this declaration lexically is inside a function.
- /// It recognizes non-defining declarations as well as members of local
- /// classes:
+ /// Returns true if this declaration is lexically inside a function or inside
+ /// a variable initializer. It recognizes non-defining declarations as well
+ /// as members of local classes:
/// \code
/// void foo() { void bar(); }
/// void foo2() { class ABC { void bar(); }; }
+ /// inline int x = [](){ return 0; };
/// \endcode
- bool isLexicallyWithinFunctionOrMethod() const;
+ bool isInLocalScope() const;
/// If this decl is defined inside a function/method/block it returns
/// the corresponding DeclContext, otherwise it returns null.
diff --git a/gnu/llvm/clang/include/clang/Basic/Attr.td b/gnu/llvm/clang/include/clang/Basic/Attr.td
index 16556b5f074..763b5b993e9 100644
--- a/gnu/llvm/clang/include/clang/Basic/Attr.td
+++ b/gnu/llvm/clang/include/clang/Basic/Attr.td
@@ -685,7 +685,7 @@ def XRayLogArgs : InheritableAttr {
def PatchableFunctionEntry
: InheritableAttr,
- TargetSpecificAttr<TargetArch<["aarch64", "x86", "x86_64"]>> {
+ TargetSpecificAttr<TargetArch<["aarch64", "aarch64_be", "x86", "x86_64"]>> {
let Spellings = [GCC<"patchable_function_entry">];
let Subjects = SubjectList<[Function, ObjCMethod]>;
let Args = [UnsignedArgument<"Count">, DefaultIntArgument<"Offset", 0>];
diff --git a/gnu/llvm/clang/include/clang/Driver/Options.td b/gnu/llvm/clang/include/clang/Driver/Options.td
index bf878919ac1..73947ae4714 100644
--- a/gnu/llvm/clang/include/clang/Driver/Options.td
+++ b/gnu/llvm/clang/include/clang/Driver/Options.td
@@ -2275,6 +2275,14 @@ def mspeculative_load_hardening : Flag<["-"], "mspeculative-load-hardening">,
Group<m_Group>, Flags<[CoreOption,CC1Option]>;
def mno_speculative_load_hardening : Flag<["-"], "mno-speculative-load-hardening">,
Group<m_Group>, Flags<[CoreOption]>;
+def mlvi_hardening : Flag<["-"], "mlvi-hardening">, Group<m_Group>, Flags<[CoreOption,DriverOption]>,
+ HelpText<"Enable all mitigations for Load Value Injection (LVI)">;
+def mno_lvi_hardening : Flag<["-"], "mno-lvi-hardening">, Group<m_Group>, Flags<[CoreOption,DriverOption]>,
+ HelpText<"Disable mitigations for Load Value Injection (LVI)">;
+def mlvi_cfi : Flag<["-"], "mlvi-cfi">, Group<m_Group>, Flags<[CoreOption,DriverOption]>,
+ HelpText<"Enable only control-flow mitigations for Load Value Injection (LVI)">;
+def mno_lvi_cfi : Flag<["-"], "mno-lvi-cfi">, Group<m_Group>, Flags<[CoreOption,DriverOption]>,
+ HelpText<"Disable control-flow mitigations for Load Value Injection (LVI)">;
def mrelax : Flag<["-"], "mrelax">, Group<m_riscv_Features_Group>,
HelpText<"Enable linker relaxation">;
diff --git a/gnu/llvm/clang/lib/AST/DeclBase.cpp b/gnu/llvm/clang/lib/AST/DeclBase.cpp
index cb4d61cac2c..cb7c7fcbd4b 100644
--- a/gnu/llvm/clang/lib/AST/DeclBase.cpp
+++ b/gnu/llvm/clang/lib/AST/DeclBase.cpp
@@ -332,13 +332,16 @@ void Decl::setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC,
}
}
-bool Decl::isLexicallyWithinFunctionOrMethod() const {
+bool Decl::isInLocalScope() const {
const DeclContext *LDC = getLexicalDeclContext();
while (true) {
if (LDC->isFunctionOrMethod())
return true;
if (!isa<TagDecl>(LDC))
return false;
+ if (const auto *CRD = dyn_cast<CXXRecordDecl>(LDC))
+ if (CRD->isLambda())
+ return true;
LDC = LDC->getLexicalParent();
}
return false;
diff --git a/gnu/llvm/clang/lib/AST/ExprConstant.cpp b/gnu/llvm/clang/lib/AST/ExprConstant.cpp
index c7997350732..7af1edb9565 100644
--- a/gnu/llvm/clang/lib/AST/ExprConstant.cpp
+++ b/gnu/llvm/clang/lib/AST/ExprConstant.cpp
@@ -8593,6 +8593,10 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
static bool EvaluateArrayNewInitList(EvalInfo &Info, LValue &This,
APValue &Result, const InitListExpr *ILE,
QualType AllocType);
+static bool EvaluateArrayNewConstructExpr(EvalInfo &Info, LValue &This,
+ APValue &Result,
+ const CXXConstructExpr *CCE,
+ QualType AllocType);
bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
if (!Info.getLangOpts().CPlusPlus2a)
@@ -8642,6 +8646,7 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
const Expr *Init = E->getInitializer();
const InitListExpr *ResizedArrayILE = nullptr;
+ const CXXConstructExpr *ResizedArrayCCE = nullptr;
QualType AllocType = E->getAllocatedType();
if (Optional<const Expr*> ArraySize = E->getArraySize()) {
@@ -8685,7 +8690,7 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
// -- the new-initializer is a braced-init-list and the number of
// array elements for which initializers are provided [...]
// exceeds the number of elements to initialize
- if (Init) {
+ if (Init && !isa<CXXConstructExpr>(Init)) {
auto *CAT = Info.Ctx.getAsConstantArrayType(Init->getType());
assert(CAT && "unexpected type for array initializer");
@@ -8708,6 +8713,8 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
// special handling for this case when we initialize.
if (InitBound != AllocBound)
ResizedArrayILE = cast<InitListExpr>(Init);
+ } else if (Init) {
+ ResizedArrayCCE = cast<CXXConstructExpr>(Init);
}
AllocType = Info.Ctx.getConstantArrayType(AllocType, ArrayBound, nullptr,
@@ -8772,6 +8779,10 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
if (!EvaluateArrayNewInitList(Info, Result, *Val, ResizedArrayILE,
AllocType))
return false;
+ } else if (ResizedArrayCCE) {
+ if (!EvaluateArrayNewConstructExpr(Info, Result, *Val, ResizedArrayCCE,
+ AllocType))
+ return false;
} else if (Init) {
if (!EvaluateInPlace(*Val, Info, Result, Init))
return false;
@@ -9597,6 +9608,16 @@ static bool EvaluateArrayNewInitList(EvalInfo &Info, LValue &This,
.VisitInitListExpr(ILE, AllocType);
}
+static bool EvaluateArrayNewConstructExpr(EvalInfo &Info, LValue &This,
+ APValue &Result,
+ const CXXConstructExpr *CCE,
+ QualType AllocType) {
+ assert(CCE->isRValue() && CCE->getType()->isArrayType() &&
+ "not an array rvalue");
+ return ArrayExprEvaluator(Info, This, Result)
+ .VisitCXXConstructExpr(CCE, This, &Result, AllocType);
+}
+
// Return true iff the given array filler may depend on the element index.
static bool MaybeElementDependentArrayFiller(const Expr *FillerExpr) {
// For now, just whitelist non-class value-initialization and initialization
diff --git a/gnu/llvm/clang/lib/AST/RawCommentList.cpp b/gnu/llvm/clang/lib/AST/RawCommentList.cpp
index 83e8a0b942a..d7124156521 100644
--- a/gnu/llvm/clang/lib/AST/RawCommentList.cpp
+++ b/gnu/llvm/clang/lib/AST/RawCommentList.cpp
@@ -430,7 +430,7 @@ std::string RawComment::getFormattedText(const SourceManager &SourceMgr,
};
auto DropTrailingNewLines = [](std::string &Str) {
- while (Str.back() == '\n')
+ while (!Str.empty() && Str.back() == '\n')
Str.pop_back();
};
diff --git a/gnu/llvm/clang/lib/Basic/CMakeLists.txt b/gnu/llvm/clang/lib/Basic/CMakeLists.txt
index be739c70468..328e616698c 100644
--- a/gnu/llvm/clang/lib/Basic/CMakeLists.txt
+++ b/gnu/llvm/clang/lib/Basic/CMakeLists.txt
@@ -12,10 +12,10 @@ set(version_inc "${CMAKE_CURRENT_BINARY_DIR}/VCSVersion.inc")
set(generate_vcs_version_script "${LLVM_CMAKE_PATH}/GenerateVersionFromVCS.cmake")
-if(llvm_vc)
+if(llvm_vc AND LLVM_APPEND_VC_REV)
set(llvm_source_dir ${LLVM_MAIN_SRC_DIR})
endif()
-if(clang_vc)
+if(clang_vc AND LLVM_APPEND_VC_REV)
set(clang_source_dir ${CLANG_SOURCE_DIR})
endif()
diff --git a/gnu/llvm/clang/lib/Basic/Targets/PPC.h b/gnu/llvm/clang/lib/Basic/Targets/PPC.h
index 3875fd5c646..616edb03f75 100644
--- a/gnu/llvm/clang/lib/Basic/Targets/PPC.h
+++ b/gnu/llvm/clang/lib/Basic/Targets/PPC.h
@@ -276,11 +276,12 @@ public:
break;
case 'Q': // Memory operand that is an offset from a register (it is
// usually better to use `m' or `es' in asm statements)
+ Info.setAllowsRegister();
+ LLVM_FALLTHROUGH;
case 'Z': // Memory operand that is an indexed or indirect from a
// register (it is usually better to use `m' or `es' in
// asm statements)
Info.setAllowsMemory();
- Info.setAllowsRegister();
break;
case 'R': // AIX TOC entry
case 'a': // Address operand that is an indexed or indirect from a
diff --git a/gnu/llvm/clang/lib/CodeGen/CGVTables.cpp b/gnu/llvm/clang/lib/CodeGen/CGVTables.cpp
index 59631e80237..e97f7e41499 100644
--- a/gnu/llvm/clang/lib/CodeGen/CGVTables.cpp
+++ b/gnu/llvm/clang/lib/CodeGen/CGVTables.cpp
@@ -437,7 +437,8 @@ void CodeGenFunction::EmitMustTailThunk(GlobalDecl GD,
// Finish the function to maintain CodeGenFunction invariants.
// FIXME: Don't emit unreachable code.
EmitBlock(createBasicBlock());
- FinishFunction();
+
+ FinishThunk();
}
void CodeGenFunction::generateThunk(llvm::Function *Fn,
@@ -564,7 +565,7 @@ llvm::Constant *CodeGenVTables::maybeEmitThunk(GlobalDecl GD,
CGM.SetLLVMFunctionAttributesForDefinition(GD.getDecl(), ThunkFn);
// Thunks for variadic methods are special because in general variadic
- // arguments cannot be perferctly forwarded. In the general case, clang
+ // arguments cannot be perfectly forwarded. In the general case, clang
// implements such thunks by cloning the original function body. However, for
// thunks with no return adjustment on targets that support musttail, we can
// use musttail to perfectly forward the variadic arguments.
diff --git a/gnu/llvm/clang/lib/CodeGen/CMakeLists.txt b/gnu/llvm/clang/lib/CodeGen/CMakeLists.txt
index d8b3c234a1e..c300c1b021f 100644
--- a/gnu/llvm/clang/lib/CodeGen/CMakeLists.txt
+++ b/gnu/llvm/clang/lib/CodeGen/CMakeLists.txt
@@ -5,6 +5,7 @@ set(LLVM_LINK_COMPONENTS
Core
Coroutines
Coverage
+ Extensions
FrontendOpenMP
IPO
IRReader
@@ -96,8 +97,6 @@ add_clang_library(clangCodeGen
TargetInfo.cpp
VarBypassDetector.cpp
- ENABLE_PLUGINS
-
DEPENDS
${codegen_deps}
diff --git a/gnu/llvm/clang/lib/CodeGen/CodeGenModule.cpp b/gnu/llvm/clang/lib/CodeGen/CodeGenModule.cpp
index f8866ac4f7f..a735bdd814e 100644
--- a/gnu/llvm/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/gnu/llvm/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1847,9 +1847,16 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F,
else if (const auto *SA = FD->getAttr<SectionAttr>())
F->setSection(SA->getName());
+ // If we plan on emitting this inline builtin, we can't treat it as a builtin.
if (FD->isInlineBuiltinDeclaration()) {
- F->addAttribute(llvm::AttributeList::FunctionIndex,
- llvm::Attribute::NoBuiltin);
+ const FunctionDecl *FDBody;
+ bool HasBody = FD->hasBody(FDBody);
+ (void)HasBody;
+ assert(HasBody && "Inline builtin declarations should always have an "
+ "available body!");
+ if (shouldEmitFunction(FDBody))
+ F->addAttribute(llvm::AttributeList::FunctionIndex,
+ llvm::Attribute::NoBuiltin);
}
if (FD->isReplaceableGlobalAllocationFunction()) {
diff --git a/gnu/llvm/clang/lib/CodeGen/TargetInfo.cpp b/gnu/llvm/clang/lib/CodeGen/TargetInfo.cpp
index 46fe5871cb9..51d6ad0cae5 100644
--- a/gnu/llvm/clang/lib/CodeGen/TargetInfo.cpp
+++ b/gnu/llvm/clang/lib/CodeGen/TargetInfo.cpp
@@ -9677,7 +9677,8 @@ ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed,
uint64_t Size = getContext().getTypeSize(Ty);
// Pass floating point values via FPRs if possible.
- if (IsFixed && Ty->isFloatingType() && FLen >= Size && ArgFPRsLeft) {
+ if (IsFixed && Ty->isFloatingType() && !Ty->isComplexType() &&
+ FLen >= Size && ArgFPRsLeft) {
ArgFPRsLeft--;
return ABIArgInfo::getDirect();
}
diff --git a/gnu/llvm/clang/lib/Driver/SanitizerArgs.cpp b/gnu/llvm/clang/lib/Driver/SanitizerArgs.cpp
index ac9a294ee3f..60fd932fbe6 100644
--- a/gnu/llvm/clang/lib/Driver/SanitizerArgs.cpp
+++ b/gnu/llvm/clang/lib/Driver/SanitizerArgs.cpp
@@ -454,8 +454,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
<< lastArgumentForMask(D, Args, Kinds & NeedsLTO) << "-flto";
}
- if ((Kinds & SanitizerKind::ShadowCallStack) &&
- TC.getTriple().getArch() == llvm::Triple::aarch64 &&
+ if ((Kinds & SanitizerKind::ShadowCallStack) && TC.getTriple().isAArch64() &&
!llvm::AArch64::isX18ReservedByDefault(TC.getTriple()) &&
!Args.hasArg(options::OPT_ffixed_x18)) {
D.Diag(diag::err_drv_argument_only_allowed_with)
diff --git a/gnu/llvm/clang/lib/Driver/ToolChain.cpp b/gnu/llvm/clang/lib/Driver/ToolChain.cpp
index cab97b1a601..18400d9def5 100644
--- a/gnu/llvm/clang/lib/Driver/ToolChain.cpp
+++ b/gnu/llvm/clang/lib/Driver/ToolChain.cpp
@@ -954,15 +954,12 @@ SanitizerMask ToolChain::getSupportedSanitizers() const {
if (getTriple().getArch() == llvm::Triple::x86 ||
getTriple().getArch() == llvm::Triple::x86_64 ||
getTriple().getArch() == llvm::Triple::arm ||
- getTriple().getArch() == llvm::Triple::aarch64 ||
getTriple().getArch() == llvm::Triple::wasm32 ||
- getTriple().getArch() == llvm::Triple::wasm64)
+ getTriple().getArch() == llvm::Triple::wasm64 || getTriple().isAArch64())
Res |= SanitizerKind::CFIICall;
- if (getTriple().getArch() == llvm::Triple::x86_64 ||
- getTriple().getArch() == llvm::Triple::aarch64)
+ if (getTriple().getArch() == llvm::Triple::x86_64 || getTriple().isAArch64())
Res |= SanitizerKind::ShadowCallStack;
- if (getTriple().getArch() == llvm::Triple::aarch64 ||
- getTriple().getArch() == llvm::Triple::aarch64_be)
+ if (getTriple().isAArch64())
Res |= SanitizerKind::MemTag;
return Res;
}
diff --git a/gnu/llvm/clang/lib/Driver/ToolChains/Darwin.cpp b/gnu/llvm/clang/lib/Driver/ToolChains/Darwin.cpp
index 220bc8f9835..46265c1b9f1 100644
--- a/gnu/llvm/clang/lib/Driver/ToolChains/Darwin.cpp
+++ b/gnu/llvm/clang/lib/Driver/ToolChains/Darwin.cpp
@@ -1146,6 +1146,7 @@ void Darwin::addProfileRTLibs(const ArgList &Args,
addExportedSymbol(CmdArgs, "___gcov_flush");
addExportedSymbol(CmdArgs, "_flush_fn_list");
addExportedSymbol(CmdArgs, "_writeout_fn_list");
+ addExportedSymbol(CmdArgs, "_reset_fn_list");
} else {
addExportedSymbol(CmdArgs, "___llvm_profile_filename");
addExportedSymbol(CmdArgs, "___llvm_profile_raw_version");
diff --git a/gnu/llvm/clang/lib/Driver/ToolChains/Gnu.cpp b/gnu/llvm/clang/lib/Driver/ToolChains/Gnu.cpp
index a55d59cb11b..0ad9ff01a93 100644
--- a/gnu/llvm/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/gnu/llvm/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -309,7 +309,7 @@ static const char *getLDMOption(const llvm::Triple &T, const ArgList &Args) {
}
}
-static bool getPIE(const ArgList &Args, const toolchains::Linux &ToolChain) {
+static bool getPIE(const ArgList &Args, const ToolChain &TC) {
if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_static) ||
Args.hasArg(options::OPT_r) || Args.hasArg(options::OPT_static_pie))
return false;
@@ -317,17 +317,16 @@ static bool getPIE(const ArgList &Args, const toolchains::Linux &ToolChain) {
Arg *A = Args.getLastArg(options::OPT_pie, options::OPT_no_pie,
options::OPT_nopie);
if (!A)
- return ToolChain.isPIEDefault();
+ return TC.isPIEDefault();
return A->getOption().matches(options::OPT_pie);
}
-static bool getStaticPIE(const ArgList &Args,
- const toolchains::Linux &ToolChain) {
+static bool getStaticPIE(const ArgList &Args, const ToolChain &TC) {
bool HasStaticPIE = Args.hasArg(options::OPT_static_pie);
// -no-pie is an alias for -nopie. So, handling -nopie takes care of
// -no-pie as well.
if (HasStaticPIE && Args.hasArg(options::OPT_nopie)) {
- const Driver &D = ToolChain.getDriver();
+ const Driver &D = TC.getDriver();
const llvm::opt::OptTable &Opts = D.getOpts();
const char *StaticPIEName = Opts.getOptionName(options::OPT_static_pie);
const char *NoPIEName = Opts.getOptionName(options::OPT_nopie);
@@ -346,8 +345,12 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfoList &Inputs,
const ArgList &Args,
const char *LinkingOutput) const {
- const toolchains::Linux &ToolChain =
- static_cast<const toolchains::Linux &>(getToolChain());
+ // FIXME: The Linker class constructor takes a ToolChain and not a
+ // Generic_ELF, so the static_cast might return a reference to a invalid
+ // instance (see PR45061). Ideally, the Linker constructor needs to take a
+ // Generic_ELF instead.
+ const toolchains::Generic_ELF &ToolChain =
+ static_cast<const toolchains::Generic_ELF &>(getToolChain());
const Driver &D = ToolChain.getDriver();
const llvm::Triple &Triple = getToolChain().getEffectiveTriple();
@@ -418,8 +421,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
if (isAndroid)
CmdArgs.push_back("--warn-shared-textrel");
- for (const auto &Opt : ToolChain.ExtraOpts)
- CmdArgs.push_back(Opt.c_str());
+ ToolChain.addExtraOpts(CmdArgs);
CmdArgs.push_back("--eh-frame-hdr");
diff --git a/gnu/llvm/clang/lib/Driver/ToolChains/Gnu.h b/gnu/llvm/clang/lib/Driver/ToolChains/Gnu.h
index 083f74c0547..fa50b56bf95 100644
--- a/gnu/llvm/clang/lib/Driver/ToolChains/Gnu.h
+++ b/gnu/llvm/clang/lib/Driver/ToolChains/Gnu.h
@@ -356,6 +356,12 @@ public:
void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args,
Action::OffloadKind DeviceOffloadKind) const override;
+
+ virtual std::string getDynamicLinker(const llvm::opt::ArgList &Args) const {
+ return {};
+ }
+
+ virtual void addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const {}
};
} // end namespace toolchains
diff --git a/gnu/llvm/clang/lib/Driver/ToolChains/Hurd.cpp b/gnu/llvm/clang/lib/Driver/ToolChains/Hurd.cpp
index 72166ca9f35..ee91f7d73b9 100644
--- a/gnu/llvm/clang/lib/Driver/ToolChains/Hurd.cpp
+++ b/gnu/llvm/clang/lib/Driver/ToolChains/Hurd.cpp
@@ -61,8 +61,7 @@ static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args) {
return Triple.isArch32Bit() ? "lib" : "lib64";
}
-Hurd::Hurd(const Driver &D, const llvm::Triple &Triple,
- const ArgList &Args)
+Hurd::Hurd(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
: Generic_ELF(D, Triple, Args) {
std::string SysRoot = computeSysRoot();
path_list &Paths = getFilePaths();
@@ -170,3 +169,8 @@ void Hurd::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include");
}
+
+void Hurd::addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const {
+ for (const auto &Opt : ExtraOpts)
+ CmdArgs.push_back(Opt.c_str());
+}
diff --git a/gnu/llvm/clang/lib/Driver/ToolChains/Hurd.h b/gnu/llvm/clang/lib/Driver/ToolChains/Hurd.h
index 86c6c3f734d..8f88d7e8e58 100644
--- a/gnu/llvm/clang/lib/Driver/ToolChains/Hurd.h
+++ b/gnu/llvm/clang/lib/Driver/ToolChains/Hurd.h
@@ -27,9 +27,11 @@ public:
AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const override;
- virtual std::string computeSysRoot() const;
+ std::string computeSysRoot() const;
- virtual std::string getDynamicLinker(const llvm::opt::ArgList &Args) const;
+ std::string getDynamicLinker(const llvm::opt::ArgList &Args) const override;
+
+ void addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const override;
std::vector<std::string> ExtraOpts;
diff --git a/gnu/llvm/clang/lib/Driver/ToolChains/Linux.cpp b/gnu/llvm/clang/lib/Driver/ToolChains/Linux.cpp
index bff1ab1009b..6532c899492 100644
--- a/gnu/llvm/clang/lib/Driver/ToolChains/Linux.cpp
+++ b/gnu/llvm/clang/lib/Driver/ToolChains/Linux.cpp
@@ -986,3 +986,8 @@ void Linux::addProfileRTLibs(const llvm::opt::ArgList &Args,
Twine("-u", llvm::getInstrProfRuntimeHookVarName())));
ToolChain::addProfileRTLibs(Args, CmdArgs);
}
+
+void Linux::addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const {
+ for (const auto &Opt : ExtraOpts)
+ CmdArgs.push_back(Opt.c_str());
+}
diff --git a/gnu/llvm/clang/lib/Driver/ToolChains/Linux.h b/gnu/llvm/clang/lib/Driver/ToolChains/Linux.h
index f5518eac218..923ebecbd21 100644
--- a/gnu/llvm/clang/lib/Driver/ToolChains/Linux.h
+++ b/gnu/llvm/clang/lib/Driver/ToolChains/Linux.h
@@ -42,7 +42,9 @@ public:
llvm::opt::ArgStringList &CmdArgs) const override;
virtual std::string computeSysRoot() const;
- virtual std::string getDynamicLinker(const llvm::opt::ArgList &Args) const;
+ std::string getDynamicLinker(const llvm::opt::ArgList &Args) const override;
+
+ void addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const override;
std::vector<std::string> ExtraOpts;
diff --git a/gnu/llvm/clang/lib/Format/TokenAnnotator.cpp b/gnu/llvm/clang/lib/Format/TokenAnnotator.cpp
index 70bcd7048c5..8cb786a4d34 100644
--- a/gnu/llvm/clang/lib/Format/TokenAnnotator.cpp
+++ b/gnu/llvm/clang/lib/Format/TokenAnnotator.cpp
@@ -2176,6 +2176,10 @@ static bool isFunctionDeclarationName(const FormatToken &Current,
Next = Next->Next;
continue;
}
+ if (Next->is(TT_TemplateOpener) && Next->MatchingParen) {
+ Next = Next->MatchingParen;
+ continue;
+ }
break;
}
@@ -2705,20 +2709,40 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
tok::l_square));
if (Right.is(tok::star) && Left.is(tok::l_paren))
return false;
- if (Right.isOneOf(tok::star, tok::amp, tok::ampamp) &&
- (Left.is(tok::identifier) || Left.isSimpleTypeSpecifier()) &&
- // Space between the type and the * in:
- // operator void*()
- // operator char*()
- // operator /*comment*/ const char*()
- // operator volatile /*comment*/ char*()
- // operator Foo*()
- // dependent on PointerAlignment style.
- Left.Previous &&
- (Left.Previous->endsSequence(tok::kw_operator) ||
- Left.Previous->endsSequence(tok::kw_const, tok::kw_operator) ||
- Left.Previous->endsSequence(tok::kw_volatile, tok::kw_operator)))
- return (Style.PointerAlignment != FormatStyle::PAS_Left);
+ if (Right.is(tok::star) && Left.is(tok::star))
+ return false;
+ if (Right.isOneOf(tok::star, tok::amp, tok::ampamp)) {
+ const FormatToken *Previous = &Left;
+ while (Previous && !Previous->is(tok::kw_operator)) {
+ if (Previous->is(tok::identifier) || Previous->isSimpleTypeSpecifier()) {
+ Previous = Previous->getPreviousNonComment();
+ continue;
+ }
+ if (Previous->is(TT_TemplateCloser) && Previous->MatchingParen) {
+ Previous = Previous->MatchingParen->getPreviousNonComment();
+ continue;
+ }
+ if (Previous->is(tok::coloncolon)) {
+ Previous = Previous->getPreviousNonComment();
+ continue;
+ }
+ break;
+ }
+ // Space between the type and the * in:
+ // operator void*()
+ // operator char*()
+ // operator /*comment*/ const char*()
+ // operator volatile /*comment*/ char*()
+ // operator Foo*()
+ // operator C<T>*()
+ // operator std::Foo*()
+ // operator C<T>::D<U>*()
+ // dependent on PointerAlignment style.
+ if (Previous && (Previous->endsSequence(tok::kw_operator) ||
+ Previous->endsSequence(tok::kw_const, tok::kw_operator) ||
+ Previous->endsSequence(tok::kw_volatile, tok::kw_operator)))
+ return (Style.PointerAlignment != FormatStyle::PAS_Left);
+ }
const auto SpaceRequiredForArrayInitializerLSquare =
[](const FormatToken &LSquareTok, const FormatStyle &Style) {
return Style.SpacesInContainerLiterals ||
diff --git a/gnu/llvm/clang/lib/Sema/SemaTemplate.cpp b/gnu/llvm/clang/lib/Sema/SemaTemplate.cpp
index c38c724ed9b..264c903209a 100755
--- a/gnu/llvm/clang/lib/Sema/SemaTemplate.cpp
+++ b/gnu/llvm/clang/lib/Sema/SemaTemplate.cpp
@@ -3817,6 +3817,9 @@ TypeResult Sema::ActOnTagTemplateIdType(TagUseKind TUK,
SourceLocation LAngleLoc,
ASTTemplateArgsPtr TemplateArgsIn,
SourceLocation RAngleLoc) {
+ if (SS.isInvalid())
+ return TypeResult(true);
+
TemplateName Template = TemplateD.get();
// Translate the parser's template argument list in our AST format.
@@ -5925,7 +5928,9 @@ bool UnnamedLocalNoLinkageFinder::VisitDependentNameType(
bool UnnamedLocalNoLinkageFinder::VisitDependentTemplateSpecializationType(
const DependentTemplateSpecializationType* T) {
- return VisitNestedNameSpecifier(T->getQualifier());
+ if (auto *Q = T->getQualifier())
+ return VisitNestedNameSpecifier(Q);
+ return false;
}
bool UnnamedLocalNoLinkageFinder::VisitPackExpansionType(
@@ -5979,6 +5984,7 @@ bool UnnamedLocalNoLinkageFinder::VisitTagDecl(const TagDecl *Tag) {
bool UnnamedLocalNoLinkageFinder::VisitNestedNameSpecifier(
NestedNameSpecifier *NNS) {
+ assert(NNS);
if (NNS->getPrefix() && VisitNestedNameSpecifier(NNS->getPrefix()))
return true;
diff --git a/gnu/llvm/clang/lib/Sema/SemaTemplateInstantiate.cpp b/gnu/llvm/clang/lib/Sema/SemaTemplateInstantiate.cpp
index b5d2ab1f31f..c53c37ee109 100644
--- a/gnu/llvm/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/gnu/llvm/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -2343,7 +2343,7 @@ ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm,
UnparsedDefaultArgInstantiations[OldParm].push_back(NewParm);
} else if (Expr *Arg = OldParm->getDefaultArg()) {
FunctionDecl *OwningFunc = cast<FunctionDecl>(OldParm->getDeclContext());
- if (OwningFunc->isLexicallyWithinFunctionOrMethod()) {
+ if (OwningFunc->isInLocalScope()) {
// Instantiate default arguments for methods of local classes (DR1484)
// and non-defining declarations.
Sema::ContextRAII SavedContext(*this, OwningFunc);
diff --git a/gnu/llvm/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/gnu/llvm/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 37dace3bee7..f801e79c890 100755
--- a/gnu/llvm/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/gnu/llvm/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -4367,7 +4367,7 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New,
EPI.ExceptionSpec.Type != EST_None &&
EPI.ExceptionSpec.Type != EST_DynamicNone &&
EPI.ExceptionSpec.Type != EST_BasicNoexcept &&
- !Tmpl->isLexicallyWithinFunctionOrMethod()) {
+ !Tmpl->isInLocalScope()) {
FunctionDecl *ExceptionSpecTemplate = Tmpl;
if (EPI.ExceptionSpec.Type == EST_Uninstantiated)
ExceptionSpecTemplate = EPI.ExceptionSpec.SourceTemplate;
diff --git a/gnu/llvm/clang/lib/Sema/TreeTransform.h b/gnu/llvm/clang/lib/Sema/TreeTransform.h
index 0305954a278..bbc6fc6deee 100644
--- a/gnu/llvm/clang/lib/Sema/TreeTransform.h
+++ b/gnu/llvm/clang/lib/Sema/TreeTransform.h
@@ -4022,50 +4022,8 @@ template<typename Derived>
void TreeTransform<Derived>::InventTemplateArgumentLoc(
const TemplateArgument &Arg,
TemplateArgumentLoc &Output) {
- SourceLocation Loc = getDerived().getBaseLocation();
- switch (Arg.getKind()) {
- case TemplateArgument::Null:
- llvm_unreachable("null template argument in TreeTransform");
- break;
-
- case TemplateArgument::Type:
- Output = TemplateArgumentLoc(Arg,
- SemaRef.Context.getTrivialTypeSourceInfo(Arg.getAsType(), Loc));
-
- break;
-
- case TemplateArgument::Template:
- case TemplateArgument::TemplateExpansion: {
- NestedNameSpecifierLocBuilder Builder;
- TemplateName Template = Arg.getAsTemplateOrTemplatePattern();
- if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
- Builder.MakeTrivial(SemaRef.Context, DTN->getQualifier(), Loc);
- else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
- Builder.MakeTrivial(SemaRef.Context, QTN->getQualifier(), Loc);
-
- if (Arg.getKind() == TemplateArgument::Template)
- Output = TemplateArgumentLoc(Arg,
- Builder.getWithLocInContext(SemaRef.Context),
- Loc);
- else
- Output = TemplateArgumentLoc(Arg,
- Builder.getWithLocInContext(SemaRef.Context),
- Loc, Loc);
-
- break;
- }
-
- case TemplateArgument::Expression:
- Output = TemplateArgumentLoc(Arg, Arg.getAsExpr());
- break;
-
- case TemplateArgument::Declaration:
- case TemplateArgument::Integral:
- case TemplateArgument::Pack:
- case TemplateArgument::NullPtr:
- Output = TemplateArgumentLoc(Arg, TemplateArgumentLocInfo());
- break;
- }
+ Output = getSema().getTrivialTemplateArgumentLoc(
+ Arg, QualType(), getDerived().getBaseLocation());
}
template<typename Derived>
@@ -4075,12 +4033,45 @@ bool TreeTransform<Derived>::TransformTemplateArgument(
const TemplateArgument &Arg = Input.getArgument();
switch (Arg.getKind()) {
case TemplateArgument::Null:
- case TemplateArgument::Integral:
case TemplateArgument::Pack:
- case TemplateArgument::Declaration:
- case TemplateArgument::NullPtr:
llvm_unreachable("Unexpected TemplateArgument");
+ case TemplateArgument::Integral:
+ case TemplateArgument::NullPtr:
+ case TemplateArgument::Declaration: {
+ // Transform a resolved template argument straight to a resolved template
+ // argument. We get here when substituting into an already-substituted
+ // template type argument during concept satisfaction checking.
+ QualType T = Arg.getNonTypeTemplateArgumentType();
+ QualType NewT = getDerived().TransformType(T);
+ if (NewT.isNull())
+ return true;
+
+ ValueDecl *D = Arg.getKind() == TemplateArgument::Declaration
+ ? Arg.getAsDecl()
+ : nullptr;
+ ValueDecl *NewD = D ? cast_or_null<ValueDecl>(getDerived().TransformDecl(
+ getDerived().getBaseLocation(), D))
+ : nullptr;
+ if (D && !NewD)
+ return true;
+
+ if (NewT == T && D == NewD)
+ Output = Input;
+ else if (Arg.getKind() == TemplateArgument::Integral)
+ Output = TemplateArgumentLoc(
+ TemplateArgument(getSema().Context, Arg.getAsIntegral(), NewT),
+ TemplateArgumentLocInfo());
+ else if (Arg.getKind() == TemplateArgument::NullPtr)
+ Output = TemplateArgumentLoc(TemplateArgument(NewT, /*IsNullPtr=*/true),
+ TemplateArgumentLocInfo());
+ else
+ Output = TemplateArgumentLoc(TemplateArgument(NewD, NewT),
+ TemplateArgumentLocInfo());
+
+ return false;
+ }
+
case TemplateArgument::Type: {
TypeSourceInfo *DI = Input.getTypeSourceInfo();
if (!DI)
@@ -11837,19 +11828,6 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
LSI->CallOperator = NewCallOperator;
- for (unsigned I = 0, NumParams = NewCallOperator->getNumParams();
- I != NumParams; ++I) {
- auto *P = NewCallOperator->getParamDecl(I);
- if (P->hasUninstantiatedDefaultArg()) {
- EnterExpressionEvaluationContext Eval(
- getSema(),
- Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed, P);
- ExprResult R = getDerived().TransformExpr(
- E->getCallOperator()->getParamDecl(I)->getDefaultArg());
- P->setDefaultArg(R.get());
- }
- }
-
getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
getDerived().transformedLocalDecl(E->getCallOperator(), {NewCallOperator});
diff --git a/gnu/llvm/clang/lib/Tooling/Syntax/Tokens.cpp b/gnu/llvm/clang/lib/Tooling/Syntax/Tokens.cpp
index 3df1c064923..35a35f90406 100644
--- a/gnu/llvm/clang/lib/Tooling/Syntax/Tokens.cpp
+++ b/gnu/llvm/clang/lib/Tooling/Syntax/Tokens.cpp
@@ -335,14 +335,38 @@ public:
SourceRange Range, const MacroArgs *Args) override {
if (!Collector)
return;
- // Only record top-level expansions, not those where:
+ const auto &SM = Collector->PP.getSourceManager();
+ // Only record top-level expansions that directly produce expanded tokens.
+ // This excludes those where:
// - the macro use is inside a macro body,
// - the macro appears in an argument to another macro.
- if (!MacroNameTok.getLocation().isFileID() ||
- (LastExpansionEnd.isValid() &&
- Collector->PP.getSourceManager().isBeforeInTranslationUnit(
- Range.getBegin(), LastExpansionEnd)))
+ // However macro expansion isn't really a tree, it's token rewrite rules,
+ // so there are other cases, e.g.
+ // #define B(X) X
+ // #define A 1 + B
+ // A(2)
+ // Both A and B produce expanded tokens, though the macro name 'B' comes
+ // from an expansion. The best we can do is merge the mappings for both.
+
+ // The *last* token of any top-level macro expansion must be in a file.
+ // (In the example above, see the closing paren of the expansion of B).
+ if (!Range.getEnd().isFileID())
return;
+ // If there's a current expansion that encloses this one, this one can't be
+ // top-level.
+ if (LastExpansionEnd.isValid() &&
+ !SM.isBeforeInTranslationUnit(LastExpansionEnd, Range.getEnd()))
+ return;
+
+ // If the macro invocation (B) starts in a macro (A) but ends in a file,
+ // we'll create a merged mapping for A + B by overwriting the endpoint for
+ // A's startpoint.
+ if (!Range.getBegin().isFileID()) {
+ Range.setBegin(SM.getExpansionLoc(Range.getBegin()));
+ assert(Collector->Expansions.count(Range.getBegin().getRawEncoding()) &&
+ "Overlapping macros should have same expansion location");
+ }
+
Collector->Expansions[Range.getBegin().getRawEncoding()] = Range.getEnd();
LastExpansionEnd = Range.getEnd();
}
@@ -399,197 +423,167 @@ public:
}
TokenBuffer build() && {
- buildSpelledTokens();
-
- // Walk over expanded tokens and spelled tokens in parallel, building the
- // mappings between those using source locations.
- // To correctly recover empty macro expansions, we also take locations
- // reported to PPCallbacks::MacroExpands into account as we do not have any
- // expanded tokens with source locations to guide us.
-
- // The 'eof' token is special, it is not part of spelled token stream. We
- // handle it separately at the end.
assert(!Result.ExpandedTokens.empty());
assert(Result.ExpandedTokens.back().kind() == tok::eof);
- for (unsigned I = 0; I < Result.ExpandedTokens.size() - 1; ++I) {
- // (!) I might be updated by the following call.
- processExpandedToken(I);
- }
- // 'eof' not handled in the loop, do it here.
- assert(SM.getMainFileID() ==
- SM.getFileID(Result.ExpandedTokens.back().location()));
- fillGapUntil(Result.Files[SM.getMainFileID()],
- Result.ExpandedTokens.back().location(),
- Result.ExpandedTokens.size() - 1);
- Result.Files[SM.getMainFileID()].EndExpanded = Result.ExpandedTokens.size();
+ // Tokenize every file that contributed tokens to the expanded stream.
+ buildSpelledTokens();
- // Some files might have unaccounted spelled tokens at the end, add an empty
- // mapping for those as they did not have expanded counterparts.
- fillGapsAtEndOfFiles();
+ // The expanded token stream consists of runs of tokens that came from
+ // the same source (a macro expansion, part of a file etc).
+ // Between these runs are the logical positions of spelled tokens that
+ // didn't expand to anything.
+ while (NextExpanded < Result.ExpandedTokens.size() - 1 /* eof */) {
+ // Create empty mappings for spelled tokens that expanded to nothing here.
+ // May advance NextSpelled, but NextExpanded is unchanged.
+ discard();
+ // Create mapping for a contiguous run of expanded tokens.
+ // Advances NextExpanded past the run, and NextSpelled accordingly.
+ unsigned OldPosition = NextExpanded;
+ advance();
+ if (NextExpanded == OldPosition)
+ diagnoseAdvanceFailure();
+ }
+ // If any tokens remain in any of the files, they didn't expand to anything.
+ // Create empty mappings up until the end of the file.
+ for (const auto &File : Result.Files)
+ discard(File.first);
return std::move(Result);
}
private:
- /// Process the next token in an expanded stream and move corresponding
- /// spelled tokens, record any mapping if needed.
- /// (!) \p I will be updated if this had to skip tokens, e.g. for macros.
- void processExpandedToken(unsigned &I) {
- auto L = Result.ExpandedTokens[I].location();
- if (L.isMacroID()) {
- processMacroExpansion(SM.getExpansionRange(L), I);
- return;
+ // Consume a sequence of spelled tokens that didn't expand to anything.
+ // In the simplest case, skips spelled tokens until finding one that produced
+ // the NextExpanded token, and creates an empty mapping for them.
+ // If Drain is provided, skips remaining tokens from that file instead.
+ void discard(llvm::Optional<FileID> Drain = llvm::None) {
+ SourceLocation Target =
+ Drain ? SM.getLocForEndOfFile(*Drain)
+ : SM.getExpansionLoc(
+ Result.ExpandedTokens[NextExpanded].location());
+ FileID File = SM.getFileID(Target);
+ const auto &SpelledTokens = Result.Files[File].SpelledTokens;
+ auto &NextSpelled = this->NextSpelled[File];
+
+ TokenBuffer::Mapping Mapping;
+ Mapping.BeginSpelled = NextSpelled;
+ // When dropping trailing tokens from a file, the empty mapping should
+ // be positioned within the file's expanded-token range (at the end).
+ Mapping.BeginExpanded = Mapping.EndExpanded =
+ Drain ? Result.Files[*Drain].EndExpanded : NextExpanded;
+ // We may want to split into several adjacent empty mappings.
+ // FlushMapping() emits the current mapping and starts a new one.
+ auto FlushMapping = [&, this] {
+ Mapping.EndSpelled = NextSpelled;
+ if (Mapping.BeginSpelled != Mapping.EndSpelled)
+ Result.Files[File].Mappings.push_back(Mapping);
+ Mapping.BeginSpelled = NextSpelled;
+ };
+
+ while (NextSpelled < SpelledTokens.size() &&
+ SpelledTokens[NextSpelled].location() < Target) {
+ // If we know mapping bounds at [NextSpelled, KnownEnd] (macro expansion)
+ // then we want to partition our (empty) mapping.
+ // [Start, NextSpelled) [NextSpelled, KnownEnd] (KnownEnd, Target)
+ SourceLocation KnownEnd = CollectedExpansions.lookup(
+ SpelledTokens[NextSpelled].location().getRawEncoding());
+ if (KnownEnd.isValid()) {
+ FlushMapping(); // Emits [Start, NextSpelled)
+ while (NextSpelled < SpelledTokens.size() &&
+ SpelledTokens[NextSpelled].location() <= KnownEnd)
+ ++NextSpelled;
+ FlushMapping(); // Emits [NextSpelled, KnownEnd]
+ // Now the loop contitues and will emit (KnownEnd, Target).
+ } else {
+ ++NextSpelled;
+ }
}
- if (L.isFileID()) {
- auto FID = SM.getFileID(L);
- TokenBuffer::MarkedFile &File = Result.Files[FID];
-
- fillGapUntil(File, L, I);
+ FlushMapping();
+ }
- // Skip the token.
- assert(File.SpelledTokens[NextSpelled[FID]].location() == L &&
- "no corresponding token in the spelled stream");
- ++NextSpelled[FID];
- return;
+ // Consumes the NextExpanded token and others that are part of the same run.
+ // Increases NextExpanded and NextSpelled by at least one, and adds a mapping
+ // (unless this is a run of file tokens, which we represent with no mapping).
+ void advance() {
+ const syntax::Token &Tok = Result.ExpandedTokens[NextExpanded];
+ SourceLocation Expansion = SM.getExpansionLoc(Tok.location());
+ FileID File = SM.getFileID(Expansion);
+ const auto &SpelledTokens = Result.Files[File].SpelledTokens;
+ auto &NextSpelled = this->NextSpelled[File];
+
+ if (Tok.location().isFileID()) {
+ // A run of file tokens continues while the expanded/spelled tokens match.
+ while (NextSpelled < SpelledTokens.size() &&
+ NextExpanded < Result.ExpandedTokens.size() &&
+ SpelledTokens[NextSpelled].location() ==
+ Result.ExpandedTokens[NextExpanded].location()) {
+ ++NextSpelled;
+ ++NextExpanded;
+ }
+ // We need no mapping for file tokens copied to the expanded stream.
+ } else {
+ // We found a new macro expansion. We should have its spelling bounds.
+ auto End = CollectedExpansions.lookup(Expansion.getRawEncoding());
+ assert(End.isValid() && "Macro expansion wasn't captured?");
+
+ // Mapping starts here...
+ TokenBuffer::Mapping Mapping;
+ Mapping.BeginExpanded = NextExpanded;
+ Mapping.BeginSpelled = NextSpelled;
+ // ... consumes spelled tokens within bounds we captured ...
+ while (NextSpelled < SpelledTokens.size() &&
+ SpelledTokens[NextSpelled].location() <= End)
+ ++NextSpelled;
+ // ... consumes expanded tokens rooted at the same expansion ...
+ while (NextExpanded < Result.ExpandedTokens.size() &&
+ SM.getExpansionLoc(
+ Result.ExpandedTokens[NextExpanded].location()) == Expansion)
+ ++NextExpanded;
+ // ... and ends here.
+ Mapping.EndExpanded = NextExpanded;
+ Mapping.EndSpelled = NextSpelled;
+ Result.Files[File].Mappings.push_back(Mapping);
}
}
- /// Skipped expanded and spelled tokens of a macro expansion that covers \p
- /// SpelledRange. Add a corresponding mapping.
- /// (!) \p I will be the index of the last token in an expansion after this
- /// function returns.
- void processMacroExpansion(CharSourceRange SpelledRange, unsigned &I) {
- auto FID = SM.getFileID(SpelledRange.getBegin());
- assert(FID == SM.getFileID(SpelledRange.getEnd()));
- TokenBuffer::MarkedFile &File = Result.Files[FID];
-
- fillGapUntil(File, SpelledRange.getBegin(), I);
-
- // Skip all expanded tokens from the same macro expansion.
- unsigned BeginExpanded = I;
- for (; I + 1 < Result.ExpandedTokens.size(); ++I) {
- auto NextL = Result.ExpandedTokens[I + 1].location();
- if (!NextL.isMacroID() ||
- SM.getExpansionLoc(NextL) != SpelledRange.getBegin())
- break;
+ // advance() is supposed to consume at least one token - if not, we crash.
+ void diagnoseAdvanceFailure() {
+#ifndef NDEBUG
+ // Show the failed-to-map token in context.
+ for (unsigned I = (NextExpanded < 10) ? 0 : NextExpanded - 10;
+ I < NextExpanded + 5 && I < Result.ExpandedTokens.size(); ++I) {
+ const char *L =
+ (I == NextExpanded) ? "!! " : (I < NextExpanded) ? "ok " : " ";
+ llvm::errs() << L << Result.ExpandedTokens[I].dumpForTests(SM) << "\n";
}
- unsigned EndExpanded = I + 1;
- consumeMapping(File, SM.getFileOffset(SpelledRange.getEnd()), BeginExpanded,
- EndExpanded, NextSpelled[FID]);
+#endif
+ llvm_unreachable("Couldn't map expanded token to spelled tokens!");
}
/// Initializes TokenBuffer::Files and fills spelled tokens and expanded
/// ranges for each of the files.
void buildSpelledTokens() {
for (unsigned I = 0; I < Result.ExpandedTokens.size(); ++I) {
- auto FID =
- SM.getFileID(SM.getExpansionLoc(Result.ExpandedTokens[I].location()));
+ const auto &Tok = Result.ExpandedTokens[I];
+ auto FID = SM.getFileID(SM.getExpansionLoc(Tok.location()));
auto It = Result.Files.try_emplace(FID);
TokenBuffer::MarkedFile &File = It.first->second;
- File.EndExpanded = I + 1;
+ // The eof token should not be considered part of the main-file's range.
+ File.EndExpanded = Tok.kind() == tok::eof ? I : I + 1;
+
if (!It.second)
continue; // we have seen this file before.
-
// This is the first time we see this file.
File.BeginExpanded = I;
File.SpelledTokens = tokenize(FID, SM, LangOpts);
}
}
- void consumeEmptyMapping(TokenBuffer::MarkedFile &File, unsigned EndOffset,
- unsigned ExpandedIndex, unsigned &SpelledIndex) {
- consumeMapping(File, EndOffset, ExpandedIndex, ExpandedIndex, SpelledIndex);
- }
-
- /// Consumes spelled tokens that form a macro expansion and adds a entry to
- /// the resulting token buffer.
- /// (!) SpelledIndex is updated in-place.
- void consumeMapping(TokenBuffer::MarkedFile &File, unsigned EndOffset,
- unsigned BeginExpanded, unsigned EndExpanded,
- unsigned &SpelledIndex) {
- // We need to record this mapping before continuing.
- unsigned MappingBegin = SpelledIndex;
- ++SpelledIndex;
-
- bool HitMapping =
- tryConsumeSpelledUntil(File, EndOffset + 1, SpelledIndex).hasValue();
- (void)HitMapping;
- assert(!HitMapping && "recursive macro expansion?");
-
- TokenBuffer::Mapping M;
- M.BeginExpanded = BeginExpanded;
- M.EndExpanded = EndExpanded;
- M.BeginSpelled = MappingBegin;
- M.EndSpelled = SpelledIndex;
-
- File.Mappings.push_back(M);
- }
-
- /// Consumes spelled tokens until location \p L is reached and adds a mapping
- /// covering the consumed tokens. The mapping will point to an empty expanded
- /// range at position \p ExpandedIndex.
- void fillGapUntil(TokenBuffer::MarkedFile &File, SourceLocation L,
- unsigned ExpandedIndex) {
- assert(L.isFileID());
- FileID FID;
- unsigned Offset;
- std::tie(FID, Offset) = SM.getDecomposedLoc(L);
-
- unsigned &SpelledIndex = NextSpelled[FID];
- unsigned MappingBegin = SpelledIndex;
- while (true) {
- auto EndLoc = tryConsumeSpelledUntil(File, Offset, SpelledIndex);
- if (SpelledIndex != MappingBegin) {
- TokenBuffer::Mapping M;
- M.BeginSpelled = MappingBegin;
- M.EndSpelled = SpelledIndex;
- M.BeginExpanded = M.EndExpanded = ExpandedIndex;
- File.Mappings.push_back(M);
- }
- if (!EndLoc)
- break;
- consumeEmptyMapping(File, SM.getFileOffset(*EndLoc), ExpandedIndex,
- SpelledIndex);
-
- MappingBegin = SpelledIndex;
- }
- };
-
- /// Consumes spelled tokens until it reaches Offset or a mapping boundary,
- /// i.e. a name of a macro expansion or the start '#' token of a PP directive.
- /// (!) NextSpelled is updated in place.
- ///
- /// returns None if \p Offset was reached, otherwise returns the end location
- /// of a mapping that starts at \p NextSpelled.
- llvm::Optional<SourceLocation>
- tryConsumeSpelledUntil(TokenBuffer::MarkedFile &File, unsigned Offset,
- unsigned &NextSpelled) {
- for (; NextSpelled < File.SpelledTokens.size(); ++NextSpelled) {
- auto L = File.SpelledTokens[NextSpelled].location();
- if (Offset <= SM.getFileOffset(L))
- return llvm::None; // reached the offset we are looking for.
- auto Mapping = CollectedExpansions.find(L.getRawEncoding());
- if (Mapping != CollectedExpansions.end())
- return Mapping->second; // found a mapping before the offset.
- }
- return llvm::None; // no more tokens, we "reached" the offset.
- }
-
- /// Adds empty mappings for unconsumed spelled tokens at the end of each file.
- void fillGapsAtEndOfFiles() {
- for (auto &F : Result.Files) {
- if (F.second.SpelledTokens.empty())
- continue;
- fillGapUntil(F.second, F.second.SpelledTokens.back().endLocation(),
- F.second.EndExpanded);
- }
- }
-
TokenBuffer Result;
- /// For each file, a position of the next spelled token we will consume.
- llvm::DenseMap<FileID, unsigned> NextSpelled;
+ unsigned NextExpanded = 0; // cursor in ExpandedTokens
+ llvm::DenseMap<FileID, unsigned> NextSpelled; // cursor in SpelledTokens
PPExpansions CollectedExpansions;
const SourceManager &SM;
const LangOptions &LangOpts;
diff --git a/gnu/llvm/clang/tools/libclang/CMakeLists.txt b/gnu/llvm/clang/tools/libclang/CMakeLists.txt
index bd0c945a5e1..973655361f7 100644
--- a/gnu/llvm/clang/tools/libclang/CMakeLists.txt
+++ b/gnu/llvm/clang/tools/libclang/CMakeLists.txt
@@ -44,7 +44,6 @@ set(LIBS
clangSema
clangSerialization
clangTooling
- LLVMSupport
)
if (CLANG_ENABLE_ARCMT)
diff --git a/gnu/llvm/clang/unittests/Format/FormatTest.cpp b/gnu/llvm/clang/unittests/Format/FormatTest.cpp
index a5a26b5c1e8..7f8a3795e6e 100644
--- a/gnu/llvm/clang/unittests/Format/FormatTest.cpp
+++ b/gnu/llvm/clang/unittests/Format/FormatTest.cpp
@@ -6185,7 +6185,17 @@ TEST_F(FormatTest, ReturnTypeBreakingStyle) {
"void\n"
"A::operator[]() {}\n"
"void\n"
- "A::operator!() {}\n",
+ "A::operator!() {}\n"
+ "void\n"
+ "A::operator**() {}\n"
+ "void\n"
+ "A::operator<Foo> *() {}\n"
+ "void\n"
+ "A::operator<Foo> **() {}\n"
+ "void\n"
+ "A::operator<Foo> &() {}\n"
+ "void\n"
+ "A::operator void **() {}\n",
Style);
verifyFormat("constexpr auto\n"
"operator()() const -> reference {}\n"
@@ -6202,6 +6212,10 @@ TEST_F(FormatTest, ReturnTypeBreakingStyle) {
"constexpr auto\n"
"operator void *() const -> reference {}\n"
"constexpr auto\n"
+ "operator void **() const -> reference {}\n"
+ "constexpr auto\n"
+ "operator void *() const -> reference {}\n"
+ "constexpr auto\n"
"operator void &() const -> reference {}\n"
"constexpr auto\n"
"operator void &&() const -> reference {}\n"
@@ -14986,9 +15000,20 @@ TEST_F(FormatTest, OperatorSpacing) {
Style.PointerAlignment = FormatStyle::PAS_Right;
verifyFormat("Foo::operator*();", Style);
verifyFormat("Foo::operator void *();", Style);
+ verifyFormat("Foo::operator void **();", Style);
verifyFormat("Foo::operator()(void *);", Style);
verifyFormat("Foo::operator*(void *);", Style);
verifyFormat("Foo::operator*();", Style);
+ verifyFormat("Foo::operator**();", Style);
+ verifyFormat("Foo::operator&();", Style);
+ verifyFormat("Foo::operator<int> *();", Style);
+ verifyFormat("Foo::operator<Foo> *();", Style);
+ verifyFormat("Foo::operator<int> **();", Style);
+ verifyFormat("Foo::operator<Foo> **();", Style);
+ verifyFormat("Foo::operator<int> &();", Style);
+ verifyFormat("Foo::operator<Foo> &();", Style);
+ verifyFormat("Foo::operator<int> &&();", Style);
+ verifyFormat("Foo::operator<Foo> &&();", Style);
verifyFormat("operator*(int (*)(), class Foo);", Style);
verifyFormat("Foo::operator&();", Style);
@@ -14999,21 +15024,39 @@ TEST_F(FormatTest, OperatorSpacing) {
verifyFormat("operator&(int (&)(), class Foo);", Style);
verifyFormat("Foo::operator&&();", Style);
+ verifyFormat("Foo::operator**();", Style);
verifyFormat("Foo::operator void &&();", Style);
verifyFormat("Foo::operator()(void &&);", Style);
verifyFormat("Foo::operator&&(void &&);", Style);
verifyFormat("Foo::operator&&();", Style);
verifyFormat("operator&&(int(&&)(), class Foo);", Style);
+ verifyFormat("operator const nsTArrayRight<E> &()", Style);
+ verifyFormat("[[nodiscard]] operator const nsTArrayRight<E, Allocator> &()",
+ Style);
+ verifyFormat("operator void **()", Style);
+ verifyFormat("operator const FooRight<Object> &()", Style);
+ verifyFormat("operator const FooRight<Object> *()", Style);
+ verifyFormat("operator const FooRight<Object> **()", Style);
Style.PointerAlignment = FormatStyle::PAS_Left;
verifyFormat("Foo::operator*();", Style);
+ verifyFormat("Foo::operator**();", Style);
verifyFormat("Foo::operator void*();", Style);
+ verifyFormat("Foo::operator void**();", Style);
verifyFormat("Foo::operator/*comment*/ void*();", Style);
verifyFormat("Foo::operator/*a*/ const /*b*/ void*();", Style);
verifyFormat("Foo::operator/*a*/ volatile /*b*/ void*();", Style);
verifyFormat("Foo::operator()(void*);", Style);
verifyFormat("Foo::operator*(void*);", Style);
verifyFormat("Foo::operator*();", Style);
+ verifyFormat("Foo::operator<int>*();", Style);
+ verifyFormat("Foo::operator<Foo>*();", Style);
+ verifyFormat("Foo::operator<int>**();", Style);
+ verifyFormat("Foo::operator<Foo>**();", Style);
+ verifyFormat("Foo::operator<int>&();", Style);
+ verifyFormat("Foo::operator<Foo>&();", Style);
+ verifyFormat("Foo::operator<int>&&();", Style);
+ verifyFormat("Foo::operator<Foo>&&();", Style);
verifyFormat("operator*(int (*)(), class Foo);", Style);
verifyFormat("Foo::operator&();", Style);
@@ -15035,6 +15078,21 @@ TEST_F(FormatTest, OperatorSpacing) {
verifyFormat("Foo::operator&&(void&&);", Style);
verifyFormat("Foo::operator&&();", Style);
verifyFormat("operator&&(int(&&)(), class Foo);", Style);
+ verifyFormat("operator const nsTArrayLeft<E>&()", Style);
+ verifyFormat("[[nodiscard]] operator const nsTArrayLeft<E, Allocator>&()",
+ Style);
+ verifyFormat("operator void**()", Style);
+ verifyFormat("operator const FooLeft<Object>&()", Style);
+ verifyFormat("operator const FooLeft<Object>*()", Style);
+ verifyFormat("operator const FooLeft<Object>**()", Style);
+
+ // PR45107
+ verifyFormat("operator Vector<String>&();", Style);
+ verifyFormat("operator const Vector<String>&();", Style);
+ verifyFormat("operator foo::Bar*();", Style);
+ verifyFormat("operator const Foo<X>::Bar<Y>*();", Style);
+ verifyFormat("operator/*a*/ const /*b*/ Foo /*c*/<X> /*d*/ ::Bar<Y>*();",
+ Style);
Style.PointerAlignment = FormatStyle::PAS_Middle;
verifyFormat("Foo::operator*();", Style);
diff --git a/gnu/llvm/clang/unittests/Tooling/Syntax/TokensTest.cpp b/gnu/llvm/clang/unittests/Tooling/Syntax/TokensTest.cpp
index b2ad3859104..f1e2dda963c 100644
--- a/gnu/llvm/clang/unittests/Tooling/Syntax/TokensTest.cpp
+++ b/gnu/llvm/clang/unittests/Tooling/Syntax/TokensTest.cpp
@@ -470,11 +470,28 @@ file './input.cpp'
mappings:
['#'_0, 'int'_7) => ['int'_0, 'int'_0)
['FOO'_10, '<eof>'_11) => ['10'_3, '<eof>'_7)
-)"}};
+)"},
+ {R"cpp(
+ #define NUM 42
+ #define ID(a) a
+ #define M 1 + ID
+ M(NUM)
+ )cpp",
+ R"(expanded tokens:
+ 1 + 42
+file './input.cpp'
+ spelled tokens:
+ # define NUM 42 # define ID ( a ) a # define M 1 + ID M ( NUM )
+ mappings:
+ ['#'_0, 'M'_17) => ['1'_0, '1'_0)
+ ['M'_17, '<eof>'_21) => ['1'_0, '<eof>'_3)
+)"},
+ };
- for (auto &Test : TestCases)
- EXPECT_EQ(Test.second, collectAndDump(Test.first))
- << collectAndDump(Test.first);
+ for (auto &Test : TestCases) {
+ std::string Dump = collectAndDump(Test.first);
+ EXPECT_EQ(Test.second, Dump) << Dump;
+ }
}
TEST_F(TokenCollectorTest, SpecialTokens) {
diff --git a/gnu/llvm/clang/utils/TableGen/ClangAttrEmitter.cpp b/gnu/llvm/clang/utils/TableGen/ClangAttrEmitter.cpp
index 4c3742c8e33..2fce9d42813 100644
--- a/gnu/llvm/clang/utils/TableGen/ClangAttrEmitter.cpp
+++ b/gnu/llvm/clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -2825,6 +2825,7 @@ void EmitClangAttrPCHRead(RecordKeeper &Records, raw_ostream &OS) {
if (R.isSubClassOf(InhClass))
OS << " bool isInherited = Record.readInt();\n";
OS << " bool isImplicit = Record.readInt();\n";
+ OS << " bool isPackExpansion = Record.readInt();\n";
ArgRecords = R.getValueAsListOfDefs("Args");
Args.clear();
for (const auto *Arg : ArgRecords) {
@@ -2840,6 +2841,7 @@ void EmitClangAttrPCHRead(RecordKeeper &Records, raw_ostream &OS) {
if (R.isSubClassOf(InhClass))
OS << " cast<InheritableAttr>(New)->setInherited(isInherited);\n";
OS << " New->setImplicit(isImplicit);\n";
+ OS << " New->setPackExpansion(isPackExpansion);\n";
OS << " break;\n";
OS << " }\n";
}
@@ -2866,6 +2868,7 @@ void EmitClangAttrPCHWrite(RecordKeeper &Records, raw_ostream &OS) {
if (R.isSubClassOf(InhClass))
OS << " Record.push_back(SA->isInherited());\n";
OS << " Record.push_back(A->isImplicit());\n";
+ OS << " Record.push_back(A->isPackExpansion());\n";
for (const auto *Arg : Args)
createArgument(*Arg, R.getName())->writePCHWrite(OS);