[PATCH] Add getter methods for arguments, ranges and fix-it hints to PartialDiagnostic
Stephan Tolksdorf
st at quanttec.com
Wed Mar 12 11:11:50 PDT 2014
Hi rsmith,
Add getter methods for arguments, ranges and fix-it hints to PartialDiagnostic
I copied the methods from Diagnostic.h and adapted them to the different storage. I've also modified getFixItHints to return an ArrayRef instead of a pointer.
I need the argument and range accessors for improving the enable-if SFINAE diagnostics.
http://llvm-reviews.chandlerc.com/D3060
Files:
include/clang/Basic/PartialDiagnostic.h
unittests/Basic/CMakeLists.txt
unittests/Basic/PartialDiagnosticTest.cpp
Index: include/clang/Basic/PartialDiagnostic.h
===================================================================
--- include/clang/Basic/PartialDiagnostic.h
+++ include/clang/Basic/PartialDiagnostic.h
@@ -272,6 +272,89 @@
unsigned getDiagID() const { return DiagID; }
+ /// \brief Return the number of arguments (excluding source ranges or fix-it
+ /// hints) stored for this diagnostic.
+ unsigned getNumArgs() const {
+ return DiagStorage ? DiagStorage->NumDiagArgs : 0;
+ }
+
+ /// \brief Return the kind of the specified index.
+ ///
+ /// Based on the kind of argument, the accessors below can be used to get
+ /// the value.
+ ///
+ /// \pre Idx < getNumArgs()
+ DiagnosticsEngine::ArgumentKind getArgKind(unsigned Idx) const {
+ assert(Idx < getNumArgs() && "Argument index out of range!");
+ return (DiagnosticsEngine::ArgumentKind)DiagStorage->DiagArgumentsKind[Idx];
+ }
+
+ /// \brief Return the provided argument string specified by \p Idx.
+ /// \pre getArgKind(Idx) == DiagnosticsEngine::ak_std_string
+ const std::string &getArgStdStr(unsigned Idx) const {
+ assert(getArgKind(Idx) == DiagnosticsEngine::ak_std_string &&
+ "invalid argument accessor!");
+ return DiagStorage->DiagArgumentsStr[Idx];
+ }
+
+ /// \brief Return the specified C string argument.
+ /// \pre getArgKind(Idx) == DiagnosticsEngine::ak_c_string
+ const char *getArgCStr(unsigned Idx) const {
+ assert(getArgKind(Idx) == DiagnosticsEngine::ak_c_string &&
+ "invalid argument accessor!");
+ return reinterpret_cast<const char *>(DiagStorage->DiagArgumentsVal[Idx]);
+ }
+
+ /// \brief Return the specified signed integer argument.
+ /// \pre getArgKind(Idx) == DiagnosticsEngine::ak_sint
+ int getArgSInt(unsigned Idx) const {
+ assert(getArgKind(Idx) == DiagnosticsEngine::ak_sint &&
+ "invalid argument accessor!");
+ return (int)DiagStorage->DiagArgumentsVal[Idx];
+ }
+
+ /// \brief Return the specified unsigned integer argument.
+ /// \pre getArgKind(Idx) == DiagnosticsEngine::ak_uint
+ unsigned getArgUInt(unsigned Idx) const {
+ assert(getArgKind(Idx) == DiagnosticsEngine::ak_uint &&
+ "invalid argument accessor!");
+ return (unsigned)DiagStorage->DiagArgumentsVal[Idx];
+ }
+
+ /// \brief Return the specified IdentifierInfo argument.
+ /// \pre getArgKind(Idx) == DiagnosticsEngine::ak_identifierinfo
+ const IdentifierInfo *getArgIdentifier(unsigned Idx) const {
+ assert(getArgKind(Idx) == DiagnosticsEngine::ak_identifierinfo &&
+ "invalid argument accessor!");
+ return reinterpret_cast<IdentifierInfo *>(
+ DiagStorage->DiagArgumentsVal[Idx]);
+ }
+
+ /// \brief Return the specified non-string argument in an opaque form.
+ /// \pre getArgKind(Idx) != DiagnosticsEngine::ak_std_string
+ intptr_t getRawArg(unsigned Idx) const {
+ assert(getArgKind(Idx) != DiagnosticsEngine::ak_std_string &&
+ "invalid argument accessor!");
+ return DiagStorage->DiagArgumentsVal[Idx];
+ }
+
+ /// \brief Return an array reference for this diagnostic's ranges.
+ /// The returned array reference gets invalidated if this diagnostics's
+ /// storage is reset.
+ ArrayRef<CharSourceRange> getRanges() const {
+ return !DiagStorage ? ArrayRef<CharSourceRange>()
+ : llvm::makeArrayRef(DiagStorage->DiagRanges,
+ DiagStorage->NumDiagRanges);
+ }
+
+ /// \brief Return an array reference for this diagnostic's fix-it hints.
+ ///
+ /// The returned array reference gets invalidated if another fix-it hint is
+ /// added to the diagnostic or if this diagnostics's storage is reset.
+ ArrayRef<FixItHint> getFixItHints() const {
+ return DiagStorage ? DiagStorage->FixItHints : ArrayRef<FixItHint>();
+ }
+
void AddTaggedVal(intptr_t V, DiagnosticsEngine::ArgumentKind Kind) const {
if (!DiagStorage)
DiagStorage = getStorage();
Index: unittests/Basic/CMakeLists.txt
===================================================================
--- unittests/Basic/CMakeLists.txt
+++ unittests/Basic/CMakeLists.txt
@@ -5,6 +5,7 @@
add_clang_unittest(BasicTests
CharInfoTest.cpp
FileManagerTest.cpp
+ PartialDiagnosticTest.cpp
SourceManagerTest.cpp
VirtualFileSystemTest.cpp
)
Index: unittests/Basic/PartialDiagnosticTest.cpp
===================================================================
--- /dev/null
+++ unittests/Basic/PartialDiagnosticTest.cpp
@@ -0,0 +1,59 @@
+//===- unittests/Basic/PartialDiagnostic.cpp -- PartialDiagnostic tests ---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace clang;
+
+TEST(PartialDiagnosticTest, getAccessors) {
+ PartialDiagnostic::StorageAllocator Allocator;
+
+ PartialDiagnostic PD(1, Allocator);
+ EXPECT_EQ(PD.getNumArgs(), 0);
+ EXPECT_EQ(PD.getRanges().size(), 0);
+ EXPECT_EQ(PD.getFixItHints().size(), 0);
+ EXPECT_TRUE(!PD.hasStorage());
+
+ PD << -1;
+ EXPECT_TRUE(PD.hasStorage());
+ EXPECT_EQ(PD.getNumArgs(), 1);
+ EXPECT_EQ(PD.getArgKind(0), DiagnosticsEngine::ak_sint);
+ EXPECT_EQ(PD.getArgSInt(0), -1);
+
+ PD << 2u;
+ EXPECT_EQ(PD.getArgUInt(1), 2);
+
+ std::string Str("std::string");
+ PD << Str;
+ EXPECT_EQ(PD.getArgStdStr(2), Str);
+
+ const char *CStr("C-string");
+ PD << CStr;
+ EXPECT_TRUE((const void *)PD.getArgCStr(3) == (const void *)CStr);
+
+ IdentifierInfo II;
+ PD << &II;
+ EXPECT_TRUE(PD.getArgIdentifier(4) == &II);
+ EXPECT_TRUE(PD.getRawArg(4) == (intptr_t)&II);
+
+ SourceLocation Loc1 = SourceLocation::getFromRawEncoding(1);
+ SourceLocation Loc2 = SourceLocation::getFromRawEncoding(2);
+ CharSourceRange Range(SourceRange(Loc1, Loc2), false);
+ PD << Range;
+ EXPECT_EQ(PD.getRanges().size(), 1);
+ EXPECT_EQ(PD.getRanges()[0].getAsRange(), Range.getAsRange());
+
+ FixItHint Hint = FixItHint::CreateInsertion(Loc1, "Insert");
+ PD << Hint;
+ EXPECT_EQ(PD.getFixItHints().size(), 1);
+ EXPECT_EQ(PD.getFixItHints()[0].CodeToInsert, "Insert");
+}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D3060.1.patch
Type: text/x-patch
Size: 6389 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140312/09b9ce61/attachment.bin>
More information about the cfe-commits
mailing list