summaryrefslogtreecommitdiffstats
path: root/tests/preprocessor
diff options
context:
space:
mode:
authorTim Foley <tfoleyNV@users.noreply.github.com>2018-08-27 12:33:35 -0700
committerGitHub <noreply@github.com>2018-08-27 12:33:35 -0700
commit9a9733091cc7c9628e445313785d561deb229072 (patch)
treec15aca8a54dc36ab5c1671591b86ae7e1895b382 /tests/preprocessor
parent6a8ad6eb4cab72c18de48762768e04d08b60a21c (diff)
Add basic support for #pragma once (#630)
* Improve diagnostic messages for function redefinition The front-end was using internal "not implemented" errors instead of friendly user-facing errors to handle: * Redefinition of a function (same signature and both have bodies) * Multiple function declarations/definitions with the same parameter signature, but differnet return types This change simply turns both of these into reasonably friendly errors that explain what went wrong and point to the previous definition/declaration as appropriate. * Add support for detecting #pragma directives and handling them The logic here mirrors what was set up for preprocessor directives, just for "sub-directives" in this case. The only case here is the default one, which now reports a warning for directives we don't understand. * Add basic support for #pragma once Fixes #494 The approach here is simplistic in the extreme. When we see a `#pragma once` directive, we put the current file path (the location of the `#pragma` directive, as reported by our source manager) into a set, and then any paths in that set are ignored by subsequent `#include` directives. This should work for simple cases of `#pragma once`, but it is likely to fail in a variety of cases because our filesystem layer currently makes no attempt to normalize/canonicalize paths. Improving the robustness of the solution is left to future work. This change includes a simple test case to confirm that a second `#include` of a file with a `#pragma once` is successfully ignored.
Diffstat (limited to 'tests/preprocessor')
-rw-r--r--tests/preprocessor/pragma-once-a.h6
-rw-r--r--tests/preprocessor/pragma-once-b.h5
-rw-r--r--tests/preprocessor/pragma-once.slang42
3 files changed, 53 insertions, 0 deletions
diff --git a/tests/preprocessor/pragma-once-a.h b/tests/preprocessor/pragma-once-a.h
new file mode 100644
index 000000000..6601919e4
--- /dev/null
+++ b/tests/preprocessor/pragma-once-a.h
@@ -0,0 +1,6 @@
+// pragma-once-a.h
+#pragma once
+
+// Used by the `pragma-once.slang` test
+
+float foo(float x) { return x; }
diff --git a/tests/preprocessor/pragma-once-b.h b/tests/preprocessor/pragma-once-b.h
new file mode 100644
index 000000000..3bb45bd44
--- /dev/null
+++ b/tests/preprocessor/pragma-once-b.h
@@ -0,0 +1,5 @@
+// pragma-once-b.h
+
+// Used by the `pragma-once.slang` test
+
+#define BAR foo
diff --git a/tests/preprocessor/pragma-once.slang b/tests/preprocessor/pragma-once.slang
new file mode 100644
index 000000000..fe805f82f
--- /dev/null
+++ b/tests/preprocessor/pragma-once.slang
@@ -0,0 +1,42 @@
+//TEST(smoke):SIMPLE:
+
+// Test support for `#pragma once`
+
+// We will include two header files:
+// one that uses `#pragma once`, and
+// one that doesn't.
+//
+// The first file defines a function `foo()`,
+// and the second defines a macro `BAR`
+//
+#include "pragma-once-a.h"
+#include "pragma-once-b.h"
+
+// We will include the files again, and
+// before we do so we need to undefine
+// the macro from the second file so
+// that it doesn't get a redefinition diagnostic.
+//
+#undef BAR
+//
+// We don't do anything about the function
+// in the first file, because we expect
+// the `#pragma once` to cause it to be
+// ignored on this second time.
+//
+#include "pragma-once-a.h"
+#include "pragma-once-b.h"
+
+// Now let's use both the function and the
+// macro, to confirm that they are both
+// defined as expected.
+//
+// Note: if we accidentally include file
+// `a.h` more than once, we'd expect to
+// get an error here, because the two
+// function definitions conflict.
+//
+float test(float x)
+{
+ return foo(x) + BAR(x);
+}