[Lldb-commits] [lldb] r138383 - in /lldb/trunk: include/lldb/Core/ include/lldb/Expression/ source/Commands/ source/Expression/ test/expression_command/persistent_types/

Sean Callanan scallanan at apple.com
Tue Aug 23 14:20:51 PDT 2011


Author: spyffe
Date: Tue Aug 23 16:20:51 2011
New Revision: 138383

URL: http://llvm.org/viewvc/llvm-project?rev=138383&view=rev
Log:
Added support for persistent types to the
expression parser.  You can use a persistent
type like this:

(lldb) expr struct $foo { int a; int b; };
(lldb) struct $foo i; i.a = 2; i.b = 3; i
($foo) $0 = {
  (int) a = 2
  (int) b = 3
}

typedefs work similarly.

This patch affects the following files:

test/expression_command/persistent_types/*
  A test case for persistent types,
  in particular structs and typedefs.

ClangForward.h
  Added TypeDecl, needed to declare some
  functions in ASTResultSynthesizer.h

ClangPersistentVariables.[h,cpp]
  Added a list of persistent types to the
  persistent variable store.

ASTResultSynthesizer.[h,cpp]
  Made the AST result synthesizer iterate
  across TypeDecls in the expression, and
  record any persistent types found.  Also
  made a minor documentation fix.

ClangUserExpression.[h,cpp]
  Extended the user expression class to
  keep the state needed to report the
  persistent variable store for the target
  to the AST result synthesizers. 

  Also introduced a new error code for
  expressions that executed normally but
  did not return a result.

CommandObjectExpression.cpp
  Improved output for expressions (like 
  declarations of new persistent types) that
  don't return a result.  This is no longer
  treated as an error.

Added:
    lldb/trunk/test/expression_command/persistent_types/
    lldb/trunk/test/expression_command/persistent_types/Makefile
    lldb/trunk/test/expression_command/persistent_types/TestPersistentTypes.py
    lldb/trunk/test/expression_command/persistent_types/main.c
Modified:
    lldb/trunk/include/lldb/Core/ClangForward.h
    lldb/trunk/include/lldb/Expression/ASTResultSynthesizer.h
    lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h
    lldb/trunk/include/lldb/Expression/ClangUserExpression.h
    lldb/trunk/source/Commands/CommandObjectExpression.cpp
    lldb/trunk/source/Expression/ASTResultSynthesizer.cpp
    lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
    lldb/trunk/source/Expression/ClangExpressionParser.cpp
    lldb/trunk/source/Expression/ClangPersistentVariables.cpp
    lldb/trunk/source/Expression/ClangUserExpression.cpp

Modified: lldb/trunk/include/lldb/Core/ClangForward.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ClangForward.h?rev=138383&r1=138382&r2=138383&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ClangForward.h (original)
+++ lldb/trunk/include/lldb/Core/ClangForward.h Tue Aug 23 16:20:51 2011
@@ -110,6 +110,7 @@
     class TextDiagnosticBuffer;
     class TranslationUnitDecl;
     class Type;
+    class TypeDecl;
     class TypedefDecl;
     class TypesCompatibleExpr;
     class UnaryOperator;

Modified: lldb/trunk/include/lldb/Expression/ASTResultSynthesizer.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ASTResultSynthesizer.h?rev=138383&r1=138382&r2=138383&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ASTResultSynthesizer.h (original)
+++ lldb/trunk/include/lldb/Expression/ASTResultSynthesizer.h Tue Aug 23 16:20:51 2011
@@ -44,9 +44,15 @@
     /// @param[in] desired_type
     ///     The type that the result should have.  May be initialized with a
     ///     NULL type, in which case the type is inferred.
+    ///
+    /// @param[in] scratch_ast_context
+    ///     If non-NULL, an AST context to populate with the persistent types
+    ///     found in the expression.
     //----------------------------------------------------------------------
     ASTResultSynthesizer(clang::ASTConsumer *passthrough,
-                         TypeFromUser desired_type);
+                         TypeFromUser desired_type,
+                         clang::ASTContext &scratch_ast_context,
+                         ClangPersistentVariables &persistent_vars);
     
     //----------------------------------------------------------------------
     /// Destructor
@@ -140,18 +146,43 @@
     bool SynthesizeFunctionResult(clang::FunctionDecl *FunDecl);
     
     //----------------------------------------------------------------------
-    /// Process a functionbody and produce the result variable and 
+    /// Process a function body and produce the result variable and 
     /// initialization
     ///
     /// @param[in] Body
     ///     The body of the function.
+    ///
+    /// @param[in] DC
+    ///     The DeclContext of the function, into which the result variable
+    ///     is inserted.
     //----------------------------------------------------------------------
     bool SynthesizeBodyResult(clang::CompoundStmt *Body,
                               clang::DeclContext *DC);
     
+    //----------------------------------------------------------------------
+    /// Given a DeclContext for a function or method, find all types
+    /// declared in the context and record any persistent types found.
+    ///
+    /// @param[in] FunDeclCtx
+    ///     The context for the function to process.
+    //----------------------------------------------------------------------
+    void RecordPersistentTypes(clang::DeclContext *FunDeclCtx);
+    
+    //----------------------------------------------------------------------
+    /// Given a TypeDecl, if it declares a type whose name starts with a
+    /// dollar sign, register it as a pointer type in the target's scratch
+    /// AST context.
+    ///
+    /// @param[in] Body
+    ///     The body of the function.
+    //----------------------------------------------------------------------
+    void MaybeRecordPersistentType(clang::TypeDecl *D);
+    
     clang::ASTContext *m_ast_context;           ///< The AST context to use for identifiers and types.
     clang::ASTConsumer *m_passthrough;          ///< The ASTConsumer down the chain, for passthrough.  NULL if it's a SemaConsumer.
     clang::SemaConsumer *m_passthrough_sema;    ///< The SemaConsumer down the chain, for passthrough.  NULL if it's an ASTConsumer.
+    clang::ASTContext &m_scratch_ast_context;   ///< The AST context to install persistent types into.
+    ClangPersistentVariables &m_persistent_vars;///< The persistent variable manager to register persistent types with.
     clang::Sema *m_sema;                        ///< The Sema to use.
     TypeFromUser m_desired_type;                ///< If non-NULL, the type to coerce the result to.
 };

Modified: lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h?rev=138383&r1=138382&r2=138383&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h Tue Aug 23 16:20:51 2011
@@ -11,10 +11,11 @@
 #define liblldb_ClangPersistentVariables_h_
 
 #include "lldb/Expression/ClangExpressionVariable.h"
+#include "llvm/ADT/DenseMap.h"
 
 namespace lldb_private
 {
-
+    
 //----------------------------------------------------------------------
 /// @class ClangPersistentVariables ClangPersistentVariables.h "lldb/Expression/ClangPersistentVariables.h"
 /// @brief Manages persistent values that need to be preserved between expression invocations.
@@ -52,8 +53,18 @@
     ConstString
     GetNextPersistentVariableName ();
 
+    void
+    RegisterPersistentType (const ConstString &name,
+                            clang::TypeDecl *tag_decl);
+    
+    clang::TypeDecl *
+    GetPersistentType (const ConstString &name);
+    
 private:
-    uint32_t m_next_persistent_variable_id;   ///< The counter used by GetNextResultName().
+    uint32_t                                                m_next_persistent_variable_id;  ///< The counter used by GetNextResultName().
+    
+    typedef llvm::DenseMap<const char *, clang::TypeDecl *> PersistentTypeMap;
+    PersistentTypeMap                                       m_persistent_types;             ///< The persistent types declared by the user.
 };
 
 }

Modified: lldb/trunk/include/lldb/Expression/ClangUserExpression.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangUserExpression.h?rev=138383&r1=138382&r2=138383&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangUserExpression.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangUserExpression.h Tue Aug 23 16:20:51 2011
@@ -290,7 +290,8 @@
               const char *expr_prefix,
               lldb::ValueObjectSP &result_valobj_sp,
               Error &error);
-
+    
+    static const Error::ValueType kNoResult = 0x1001; ///< ValueObject::GetError() returns this if there is no result from the expression.
 private:
     //------------------------------------------------------------------
     /// Populate m_cplusplus and m_objetivec based on the environment.
@@ -320,6 +321,7 @@
     bool                                        m_objectivec;           ///< True if the expression is compiled as an Objective-C method (true if it was parsed when exe_ctx was in an Objective-C method).
     bool                                        m_needs_object_ptr;     ///< True if "this" or "self" must be looked up and passed in.  False if the expression doesn't really use them and they can be NULL.
     bool                                        m_const_object;         ///< True if "this" is const.
+    Target                                     *m_target;               ///< The target for storing persistent data like types and variables.
     
     lldb::ClangExpressionVariableSP             m_const_result;         ///< The statically-computed result of the expression.  NULL if it could not be computed statically or the expression has side effects.
 };

Modified: lldb/trunk/source/Commands/CommandObjectExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectExpression.cpp?rev=138383&r1=138382&r2=138383&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectExpression.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectExpression.cpp Tue Aug 23 16:20:51 2011
@@ -347,24 +347,34 @@
             }
             else
             {
-                const char *error_cstr = result_valobj_sp->GetError().AsCString();
-                if (error_cstr && error_cstr[0])
+                if (result_valobj_sp->GetError().GetError() == ClangUserExpression::kNoResult)
                 {
-                    int error_cstr_len = strlen (error_cstr);
-                    const bool ends_with_newline = error_cstr[error_cstr_len - 1] == '\n';
-                    if (strstr(error_cstr, "error:") != error_cstr)
-                        error_stream->PutCString ("error: ");
-                    error_stream->Write(error_cstr, error_cstr_len);
-                    if (!ends_with_newline)
-                        error_stream->EOL();
+                    error_stream->PutCString("<no result>\n");
+                    
+                    if (result)
+                        result->SetStatus (eReturnStatusSuccessFinishResult);
                 }
                 else
                 {
-                    error_stream->PutCString ("error: unknown error\n");
+                    const char *error_cstr = result_valobj_sp->GetError().AsCString();
+                    if (error_cstr && error_cstr[0])
+                    {
+                        int error_cstr_len = strlen (error_cstr);
+                        const bool ends_with_newline = error_cstr[error_cstr_len - 1] == '\n';
+                        if (strstr(error_cstr, "error:") != error_cstr)
+                            error_stream->PutCString ("error: ");
+                        error_stream->Write(error_cstr, error_cstr_len);
+                        if (!ends_with_newline)
+                            error_stream->EOL();
+                    }
+                    else
+                    {
+                        error_stream->PutCString ("error: unknown error\n");
+                    }
+                    
+                    if (result)
+                        result->SetStatus (eReturnStatusFailed);
                 }
-
-                if (result)
-                    result->SetStatus (eReturnStatusFailed);
             }
         }
     }

Modified: lldb/trunk/source/Expression/ASTResultSynthesizer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ASTResultSynthesizer.cpp?rev=138383&r1=138382&r2=138383&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ASTResultSynthesizer.cpp (original)
+++ lldb/trunk/source/Expression/ASTResultSynthesizer.cpp Tue Aug 23 16:20:51 2011
@@ -19,19 +19,25 @@
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/raw_ostream.h"
 #include "lldb/Core/Log.h"
+#include "lldb/Expression/ClangPersistentVariables.h"
 #include "lldb/Expression/ASTResultSynthesizer.h"
+#include "lldb/Symbol/ClangASTContext.h"
 
 using namespace llvm;
 using namespace clang;
 using namespace lldb_private;
 
 ASTResultSynthesizer::ASTResultSynthesizer(ASTConsumer *passthrough,
-                                           TypeFromUser desired_type) :
+                                           TypeFromUser desired_type,
+                                           ASTContext &scratch_ast_context,
+                                           ClangPersistentVariables &persistent_vars) :
     m_ast_context (NULL),
     m_passthrough (passthrough),
     m_passthrough_sema (NULL),
     m_sema (NULL),
-    m_desired_type (desired_type)
+    m_desired_type (desired_type),
+    m_scratch_ast_context (scratch_ast_context),
+    m_persistent_vars (persistent_vars)
 {
     if (!m_passthrough)
         return;
@@ -87,6 +93,7 @@
         if (m_ast_context &&
             !method_decl->getSelector().getAsString().compare("$__lldb_expr:"))
         {
+            RecordPersistentTypes(method_decl);
             SynthesizeObjCMethodResult(method_decl);
         }
     }
@@ -95,6 +102,7 @@
         if (m_ast_context &&
             !function_decl->getNameInfo().getAsString().compare("$__lldb_expr"))
         {
+            RecordPersistentTypes(function_decl);
             SynthesizeFunctionResult(function_decl);
         }
     }
@@ -397,9 +405,51 @@
         m_passthrough->HandleTranslationUnit(Ctx);
 }
 
+void
+ASTResultSynthesizer::RecordPersistentTypes(DeclContext *FunDeclCtx)
+{
+    typedef DeclContext::specific_decl_iterator<TypeDecl> TypeDeclIterator;
+    
+    for (TypeDeclIterator i = TypeDeclIterator(FunDeclCtx->decls_begin()), 
+         e = TypeDeclIterator(FunDeclCtx->decls_end());
+         i != e;
+         ++i)
+    {
+        MaybeRecordPersistentType(*i);
+    }
+}
+
 void 
-ASTResultSynthesizer::HandleTagDeclDefinition(TagDecl *D)
+ASTResultSynthesizer::MaybeRecordPersistentType(TypeDecl *D)
 {
+    if (!D->getIdentifier())
+        return;
+    
+    StringRef name = D->getName();
+    
+    if (name.size() == 0 || name[0] != '$')
+        return;
+    
+    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+
+    ConstString name_cs(name.str().c_str());
+    
+    if (log)
+        log->Printf ("Recording persistent type %s\n", name_cs.GetCString());
+    
+    Decl *D_scratch = ClangASTContext::CopyDecl(&m_scratch_ast_context, 
+                                                m_ast_context,
+                                                D);
+    
+    TypeDecl *TD_scratch = dyn_cast<TypeDecl>(D_scratch);
+    
+    if (TD_scratch)
+        m_persistent_vars.RegisterPersistentType(name_cs, TD_scratch);
+}
+
+void 
+ASTResultSynthesizer::HandleTagDeclDefinition(TagDecl *D)
+{    
     if (m_passthrough)
         m_passthrough->HandleTagDeclDefinition(D);
 }

Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=138383&r1=138382&r2=138383&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Tue Aug 23 16:20:51 2011
@@ -1945,6 +1945,42 @@
             return;
         }
 
+        do
+        {
+            if (!m_parser_vars->m_exe_ctx->target)
+                break;
+            
+            ClangASTContext *scratch_clang_ast_context = m_parser_vars->m_exe_ctx->target->GetScratchClangASTContext();
+            
+            if (!scratch_clang_ast_context)
+                break;
+            
+            ASTContext *scratch_ast_context = scratch_clang_ast_context->getASTContext();
+            
+            if (!scratch_ast_context)
+                break;
+            
+            TypeDecl *ptype_type_decl = m_parser_vars->m_persistent_vars->GetPersistentType(name);
+
+            if (!ptype_type_decl)
+                break;
+            
+            Decl *parser_ptype_decl = ClangASTContext::CopyDecl(context.GetASTContext(), scratch_ast_context, ptype_type_decl);
+            
+            if (!parser_ptype_decl)
+                break;
+            
+            TypeDecl *parser_ptype_type_decl = dyn_cast<TypeDecl>(parser_ptype_decl);
+            
+            if (!parser_ptype_type_decl)
+                break;
+            
+            if (log)
+                log->Printf("Found persistent type %s", name.GetCString());
+            
+            context.AddNamedDecl(parser_ptype_type_decl);
+        } while (0);
+        
         ClangExpressionVariableSP pvar_sp(m_parser_vars->m_persistent_vars->GetVariable(name));
     
         if (pvar_sp)

Modified: lldb/trunk/source/Expression/ClangExpressionParser.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionParser.cpp?rev=138383&r1=138382&r2=138383&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionParser.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionParser.cpp Tue Aug 23 16:20:51 2011
@@ -234,6 +234,7 @@
     m_compiler->getLangOpts().ThreadsafeStatics = false;
     m_compiler->getLangOpts().AccessControl = false; // Debuggers get universal access
     m_compiler->getLangOpts().DollarIdents = true; // $ indicates a persistent variable name
+    //m_compiler->getLangOpts().DebuggerSupport = true; // Features specifically for debugger clients
     
     // Set CodeGen options
     m_compiler->getCodeGenOpts().EmitDeclMetadata = true;

Modified: lldb/trunk/source/Expression/ClangPersistentVariables.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangPersistentVariables.cpp?rev=138383&r1=138382&r2=138383&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangPersistentVariables.cpp (original)
+++ lldb/trunk/source/Expression/ClangPersistentVariables.cpp Tue Aug 23 16:20:51 2011
@@ -13,6 +13,8 @@
 #include "lldb/Core/StreamString.h"
 #include "lldb/Core/Value.h"
 
+#include "llvm/ADT/StringMap.h"
+
 using namespace lldb;
 using namespace lldb_private;
 
@@ -53,3 +55,21 @@
     ConstString name(name_cstr);
     return name;
 }
+
+void
+ClangPersistentVariables::RegisterPersistentType (const ConstString &name,
+                                                  clang::TypeDecl *type_decl)
+{
+    m_persistent_types.insert(std::pair<const char*, clang::TypeDecl*>(name.GetCString(), type_decl));
+}
+
+clang::TypeDecl *
+ClangPersistentVariables::GetPersistentType (const ConstString &name)
+{
+    PersistentTypeMap::const_iterator i = m_persistent_types.find(name.GetCString());
+    
+    if (i == m_persistent_types.end())
+        return NULL;
+    else
+        return i->second;
+}

Modified: lldb/trunk/source/Expression/ClangUserExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangUserExpression.cpp?rev=138383&r1=138382&r2=138383&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangUserExpression.cpp (original)
+++ lldb/trunk/source/Expression/ClangUserExpression.cpp Tue Aug 23 16:20:51 2011
@@ -53,7 +53,8 @@
     m_objectivec (false),
     m_needs_object_ptr (false),
     m_const_object (false),
-    m_const_result ()
+    m_const_result (),
+    m_target (NULL)
 {
 }
 
@@ -64,8 +65,15 @@
 clang::ASTConsumer *
 ClangUserExpression::ASTTransformer (clang::ASTConsumer *passthrough)
 {
+    ClangASTContext *clang_ast_context = m_target->GetScratchClangASTContext();
+    
+    if (!clang_ast_context)
+        return NULL;
+    
     return new ASTResultSynthesizer(passthrough,
-                                    m_desired_type);
+                                    m_desired_type,
+                                    *m_target->GetScratchClangASTContext()->getASTContext(),
+                                    m_target->GetPersistentVariables());
 }
 
 void
@@ -88,6 +96,8 @@
         
     if (!decl_context)
         return;
+    
+    m_target = exe_ctx.target;
         
     if (clang::CXXMethodDecl *method_decl = llvm::dyn_cast<clang::CXXMethodDecl>(decl_context))
     {
@@ -718,7 +728,7 @@
                     if (log)
                         log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with no result ==");
                     
-                    error.SetErrorString ("Expression did not return a result");
+                    error.SetError(ClangUserExpression::kNoResult, lldb::eErrorTypeGeneric);
                 }
             }
         }

Added: lldb/trunk/test/expression_command/persistent_types/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/expression_command/persistent_types/Makefile?rev=138383&view=auto
==============================================================================
--- lldb/trunk/test/expression_command/persistent_types/Makefile (added)
+++ lldb/trunk/test/expression_command/persistent_types/Makefile Tue Aug 23 16:20:51 2011
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/test/expression_command/persistent_types/TestPersistentTypes.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/expression_command/persistent_types/TestPersistentTypes.py?rev=138383&view=auto
==============================================================================
--- lldb/trunk/test/expression_command/persistent_types/TestPersistentTypes.py (added)
+++ lldb/trunk/test/expression_command/persistent_types/TestPersistentTypes.py Tue Aug 23 16:20:51 2011
@@ -0,0 +1,41 @@
+"""
+Test that lldb persistent types works correctly.
+"""
+
+import os, time
+import unittest2
+import lldb
+from lldbtest import *
+
+class PersistenttypesTestCase(TestBase):
+
+    mydir = os.path.join("expression_command", "persistent_types")
+
+    def test_persistent_types(self):
+        """Test that lldb persistent types works correctly."""
+        self.buildDefault()
+
+        self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+        self.runCmd("breakpoint set --name main")
+
+        self.runCmd("run", RUN_SUCCEEDED)
+
+        self.runCmd("expression struct $foo { int a; int b; };")
+
+        self.expect("expression struct $foo $my_foo; $my_foo.a = 2; $my_foo.b = 3;",
+                    startstr = "(int) $0 = 3")
+
+        self.expect("expression $my_foo",
+                    substrs = ['a = 2', 'b = 3'])
+
+        self.runCmd("expression typedef int $bar")
+
+        self.expect("expression $bar i = 5; i",
+                    startstr = "($bar) $1 = 5")
+
+if __name__ == '__main__':
+    import atexit
+    lldb.SBDebugger.Initialize()
+    atexit.register(lambda: lldb.SBDebugger.Terminate())
+    unittest2.main()

Added: lldb/trunk/test/expression_command/persistent_types/main.c
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/expression_command/persistent_types/main.c?rev=138383&view=auto
==============================================================================
--- lldb/trunk/test/expression_command/persistent_types/main.c (added)
+++ lldb/trunk/test/expression_command/persistent_types/main.c Tue Aug 23 16:20:51 2011
@@ -0,0 +1,13 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+int main (int argc, char const *argv[])
+{
+    return 0;
+}





More information about the lldb-commits mailing list