ArcsinX created this revision.
ArcsinX added reviewers: sammccall, kadircet.
Herald added subscribers: usaxena95, arphaman.
ArcsinX requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay, ilya-biryukov.
Herald added a project: clang-tools-extra.
Clang uses 4.2.1 as a default GCC version.
For projects that rely on the GCC version, this can be a problem, e.g.
#if __GNUC__ < 5
#error "Incompatible compiler"
#endif
This patch extracts the GCC version from the driver output and adds
-fgnuc-version=<extracted version> compile option to unsure that the values of
GCC macros are correct.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D107304
Files:
clang-tools-extra/clangd/QueryDriverDatabase.cpp
clang-tools-extra/clangd/test/system-include-extractor.test
Index: clang-tools-extra/clangd/test/system-include-extractor.test
===================================================================
--- clang-tools-extra/clangd/test/system-include-extractor.test
+++ clang-tools-extra/clangd/test/system-include-extractor.test
@@ -16,6 +16,7 @@
# RUN: echo 'echo " $* " | grep " --sysroot /my/sysroot/path " || exit' >> %t.dir/bin/my_driver.sh
# RUN: echo 'echo line to ignore >&2' >> %t.dir/bin/my_driver.sh
# RUN: echo 'printf "Target: arm-linux-gnueabihf\r\n" >&2' >> %t.dir/bin/my_driver.sh
+# RUN: echo 'printf "gcc version 8.3.0 (Rev2)\r\n" >&2' >> %t.dir/bin/my_driver.sh
# RUN: echo 'printf "#include <...> search starts here:\r\n" >&2' >> %t.dir/bin/my_driver.sh
# RUN: echo 'echo %t.dir/my/dir/ >&2' >> %t.dir/bin/my_driver.sh
# RUN: echo 'echo %t.dir/my/dir2/ >&2' >> %t.dir/bin/my_driver.sh
@@ -49,7 +50,7 @@
"uri": "file://INPUT_DIR/the-file.cpp",
"languageId":"cpp",
"version":1,
- "text":"#include <a.h>\n#include <b.h>\n#if !defined(__ARM_ARCH) || !defined(__gnu_linux__)\n#error \"Invalid target\"\n#endif"
+ "text":"#include <a.h>\n#include <b.h>\n#if !defined(__ARM_ARCH) || !defined(__gnu_linux__)\n#error \"Invalid target\"\n#endif\n#if !defined(__GNUC__) || __GNUC__ != 8\n#error \"Incorrect GCC version\"\n#endif"
}
}
}
Index: clang-tools-extra/clangd/QueryDriverDatabase.cpp
===================================================================
--- clang-tools-extra/clangd/QueryDriverDatabase.cpp
+++ clang-tools-extra/clangd/QueryDriverDatabase.cpp
@@ -62,6 +62,7 @@
struct DriverInfo {
std::vector<std::string> SystemIncludes;
std::string Target;
+ std::string GccVersion;
};
bool isValidTarget(llvm::StringRef Triple) {
@@ -79,6 +80,7 @@
const char SIS[] = "#include <...> search starts here:";
const char SIE[] = "End of search list.";
const char TS[] = "Target: ";
+ const char VS[] = "gcc version ";
llvm::SmallVector<llvm::StringRef> Lines;
Output.split(Lines, '\n', /*MaxSplit=*/-1, /*KeepEmpty=*/false);
@@ -89,6 +91,7 @@
} State = Initial;
bool SeenIncludes = false;
bool SeenTarget = false;
+ bool SeenVersion = false;
for (auto *It = Lines.begin(); State != Done && It != Lines.end(); ++It) {
auto Line = *It;
switch (State) {
@@ -109,6 +112,17 @@
vlog("System include extraction: target extracted: \"{0}\"",
TargetLine);
}
+ } else if (!SeenVersion && Line.trim().startswith(VS)) {
+ SeenVersion = true;
+ llvm::StringRef GccVersionLine = Line.trim();
+ GccVersionLine.consume_front(VS);
+ Info.GccVersion = GccVersionLine
+ .take_while([](unsigned char C) {
+ return C == '.' || std::isdigit(C);
+ })
+ .str();
+ vlog("System include extraction: GCC version extracted: \"{0}\"",
+ Info.GccVersion);
}
break;
case IncludesExtracting:
@@ -231,8 +245,11 @@
if (!Info)
return llvm::None;
log("System includes extractor: successfully executed {0}\n\tgot includes: "
- "\"{1}\"\n\tgot target: \"{2}\"",
- Driver, llvm::join(Info->SystemIncludes, ", "), Info->Target);
+ "\"{1}\"\n\tgot target: \"{2}\"{3}",
+ Driver, llvm::join(Info->SystemIncludes, ", "), Info->Target,
+ Info->GccVersion.empty()
+ ? std::string()
+ : llvm::formatv("\n\tgot GCC version: \"{0}\"", Info->GccVersion));
return Info;
}
@@ -260,6 +277,19 @@
return Cmd;
}
+tooling::CompileCommand &setGccVersion(tooling::CompileCommand &Cmd,
+ const std::string &GccVersion) {
+ if (!GccVersion.empty()) {
+ // We do not want to override existing GCC version with extracted one.
+ for (llvm::StringRef Arg : Cmd.CommandLine) {
+ if (Arg.startswith("-fgnuc-version"))
+ return Cmd;
+ }
+ Cmd.CommandLine.push_back("-fgnuc-version=" + GccVersion);
+ }
+ return Cmd;
+}
+
/// Converts a glob containing only ** or * into a regex.
std::string convertGlobToRegex(llvm::StringRef Glob) {
std::string RegText;
@@ -345,7 +375,9 @@
return extractSystemIncludesAndTarget(
Driver, Lang, Cmd->CommandLine, QueryDriverRegex);
})) {
- setTarget(addSystemIncludes(*Cmd, Info->SystemIncludes), Info->Target);
+ setGccVersion(setTarget(addSystemIncludes(*Cmd, Info->SystemIncludes),
+ Info->Target),
+ Info->GccVersion);
}
return Cmd;
}
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits