]> granicus.if.org Git - clang/commitdiff
Define DiagnosticBuilder<<APValue so it's easy to include APValues in
authorJeffrey Yasskin <jyasskin@google.com>
Mon, 18 Jul 2011 16:43:53 +0000 (16:43 +0000)
committerJeffrey Yasskin <jyasskin@google.com>
Mon, 18 Jul 2011 16:43:53 +0000 (16:43 +0000)
diagnostics.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@135398 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/APValue.h
lib/AST/APValue.cpp
unittests/AST/APValueTest.cpp [new file with mode: 0644]
unittests/AST/Makefile [new file with mode: 0644]
unittests/CMakeLists.txt
unittests/Makefile

index fec7d29f6d7b1c15f1912573bd71300c7ce4a607..5c8c99d85d35a56a1305f36abc027883a0f19dca 100644 (file)
@@ -19,6 +19,7 @@
 
 namespace clang {
   class CharUnits;
+  class DiagnosticBuilder;
   class Expr;
 
 /// APValue - This class implements a discriminated union of [uninitialized]
@@ -238,6 +239,10 @@ inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const APValue &V) {
   return OS;
 }
 
+// Writes a concise representation of V to DB, in a single << operation.
+const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                    const APValue &V);
+
 } // end namespace clang.
 
 #endif
index ebe99b12cdab0cb5e2e11296b2108385f29855f8..86eec3b8bb5abb131e76a48d8196b3deb9abd9be 100644 (file)
@@ -13,6 +13,8 @@
 
 #include "clang/AST/APValue.h"
 #include "clang/AST/CharUnits.h"
+#include "clang/Basic/Diagnostic.h"
+#include "llvm/ADT/SmallString.h"
 #include "llvm/Support/raw_ostream.h"
 using namespace clang;
 
@@ -118,6 +120,49 @@ void APValue::print(llvm::raw_ostream &OS) const {
   }
 }
 
+static void WriteShortAPValueToStream(llvm::raw_ostream& Out,
+                                      const APValue& V) {
+  switch (V.getKind()) {
+  default: assert(0 && "Unknown APValue kind!");
+  case APValue::Uninitialized:
+    Out << "Uninitialized";
+    break;
+  case APValue::Int:
+    Out << V.getInt();
+    break;
+  case APValue::Float:
+    Out << GetApproxValue(V.getFloat());
+    break;
+  case APValue::Vector:
+    Out << '[';
+    WriteShortAPValueToStream(Out, V.getVectorElt(0));
+    for (unsigned i = 1; i != V.getVectorLength(); ++i) {
+      Out << ", ";
+      WriteShortAPValueToStream(Out, V.getVectorElt(i));
+    }
+    Out << ']';
+    break;
+  case APValue::ComplexInt:
+    Out << V.getComplexIntReal() << "+" << V.getComplexIntImag() << "i";
+    break;
+  case APValue::ComplexFloat:
+    Out << GetApproxValue(V.getComplexFloatReal()) << "+"
+        << GetApproxValue(V.getComplexFloatImag()) << "i";
+    break;
+  case APValue::LValue:
+    Out << "LValue: <todo>";
+    break;
+  }
+}
+
+const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
+                                           const APValue &V) {
+  llvm::SmallString<64> Buffer;
+  llvm::raw_svector_ostream Out(Buffer);
+  WriteShortAPValueToStream(Out, V);
+  return DB << Out.str();
+}
+
 const Expr* APValue::getLValueBase() const {
   assert(isLValue() && "Invalid accessor");
   return ((const LV*)(const void*)Data)->Base;
diff --git a/unittests/AST/APValueTest.cpp b/unittests/AST/APValueTest.cpp
new file mode 100644 (file)
index 0000000..ae054b3
--- /dev/null
@@ -0,0 +1,79 @@
+//===- unittests/AST/APValueTest.cpp - APValue tests ---===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/APValue.h"
+
+#include "clang/Basic/Diagnostic.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
+
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace clang;
+
+namespace {
+
+class DiagnosticOutputGetter {
+  class LastDiagnosticString : public DiagnosticClient {
+    SmallString<64> LastDiagnostic;
+  public:
+    virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
+                                  const DiagnosticInfo &Info) {
+      LastDiagnostic.clear();
+      Info.FormatDiagnostic(LastDiagnostic);
+    }
+
+    StringRef get() const { return LastDiagnostic; }
+  };
+
+  const IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs;
+  const unsigned diag_just_format;
+  LastDiagnosticString LastDiagnostic;
+  Diagnostic Diag;
+
+public:
+  DiagnosticOutputGetter()
+    : DiagIDs(new DiagnosticIDs),
+      diag_just_format(DiagIDs->getCustomDiagID(DiagnosticIDs::Error, "%0")),
+      Diag(DiagIDs, &LastDiagnostic, false) {
+  }
+
+  template<typename T>
+  std::string operator()(const T& value) {
+    Diag.Report(diag_just_format) << value;
+    return LastDiagnostic.get().str();
+  }
+};
+
+TEST(APValue, Diagnostics) {
+  DiagnosticOutputGetter GetDiagnosticOutput;
+
+  EXPECT_EQ("Uninitialized", GetDiagnosticOutput(APValue()));
+  EXPECT_EQ("5", GetDiagnosticOutput(APValue(APSInt(APInt(16, 5)))));
+  EXPECT_EQ("3.141590e+00",
+            GetDiagnosticOutput(APValue(APFloat(APFloat::IEEEdouble,
+                                                "3.14159"))));
+  EXPECT_EQ("3+4i",
+            GetDiagnosticOutput(APValue(APSInt(APInt(16, 3)),
+                                        APSInt(APInt(16, 4)))));
+  EXPECT_EQ("3.200000e+00+5.700000e+00i",
+            GetDiagnosticOutput(APValue(
+                                  APFloat(APFloat::IEEEdouble, "3.2"),
+                                  APFloat(APFloat::IEEEdouble, "5.7"))));
+  APValue V[] = {
+    APValue(APSInt(APInt(16, 3))),
+    APValue(APSInt(APInt(16, 4))),
+    APValue(APSInt(APInt(16, 5)))
+  };
+  EXPECT_EQ("[3, 4, 5]",
+            GetDiagnosticOutput(APValue(V, array_lengthof(V))));
+}
+
+} // anonymous namespace
diff --git a/unittests/AST/Makefile b/unittests/AST/Makefile
new file mode 100644 (file)
index 0000000..74191d0
--- /dev/null
@@ -0,0 +1,15 @@
+##===- unittests/Frontend/Makefile -------------------------*- Makefile -*-===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+CLANG_LEVEL = ../..
+TESTNAME = AST
+LINK_COMPONENTS := support mc
+USEDLIBS = clangAST.a clangBasic.a
+
+include $(CLANG_LEVEL)/unittests/Makefile
index cb44dc59dcfc4895e13c0fb7f32cbca182ce82a8..901f167f35636e28369adab566960d6d4243924e 100644 (file)
@@ -50,6 +50,11 @@ if(SUPPORTS_NO_VARIADIC_MACROS_FLAG)
   add_definitions("-Wno-variadic-macros")
 endif()
 
+add_clang_unittest(AST
+  AST/APValueTest.cpp
+  USED_LIBS gtest gtest_main clangAST
+ )
+
 add_clang_unittest(Basic
   Basic/FileManagerTest.cpp
   USED_LIBS gtest gtest_main clangBasic
index 951e17e21771ee1e9960e7de72678000db155602..f4ce6adaa72510ce5272a91ca9295ee4d89d44a3 100644 (file)
@@ -14,7 +14,7 @@ ifndef CLANG_LEVEL
 
 IS_UNITTEST_LEVEL := 1
 CLANG_LEVEL := ..
-PARALLEL_DIRS = Basic Frontend
+PARALLEL_DIRS = AST Basic Frontend
 
 endif  # CLANG_LEVEL