[Lldb-commits] [lldb] r234922 - Added support to ClangUserExpression for importing

Sean Callanan scallanan at apple.com
Tue Apr 14 11:36:18 PDT 2015


Author: spyffe
Date: Tue Apr 14 13:36:17 2015
New Revision: 234922

URL: http://llvm.org/viewvc/llvm-project?rev=234922&view=rev
Log:
Added support to ClangUserExpression for importing
all the macros from the modules the user has loaded.
These macros are currently imported textually into
the expression's source code, which turns out not to
impose the horrific string processing overhead that
I thought it would, but I still plan to look into
performance improvements.

Also modified TestCModules to test that this works.

Modified:
    lldb/trunk/include/lldb/Core/ClangForward.h
    lldb/trunk/include/lldb/Expression/ClangModulesDeclVendor.h
    lldb/trunk/source/Expression/ClangModulesDeclVendor.cpp
    lldb/trunk/source/Expression/ClangUserExpression.cpp
    lldb/trunk/test/lang/c/modules/TestCModules.py

Modified: lldb/trunk/include/lldb/Core/ClangForward.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ClangForward.h?rev=234922&r1=234921&r2=234922&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ClangForward.h (original)
+++ lldb/trunk/include/lldb/Core/ClangForward.h Tue Apr 14 13:36:17 2015
@@ -72,11 +72,14 @@ namespace clang
     class FunctionTemplateSpecializationInfo;
     class GotoStmt;
     class HeaderSearchOptions;
+    class IdentifierInfo;
     class IdentifierTable;
     class IntegerLiteral;
     class LabelStmt;
     class LangOptions;
+    class MacroDirective;
     class MemberExpr;
+    class Module;
     class NamedDecl;
     class NamespaceDecl;
     class NonTypeTemplateParmDecl;

Modified: lldb/trunk/include/lldb/Expression/ClangModulesDeclVendor.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangModulesDeclVendor.h?rev=234922&r1=234921&r2=234922&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangModulesDeclVendor.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangModulesDeclVendor.h Tue Apr 14 13:36:17 2015
@@ -52,6 +52,9 @@ public:
     //------------------------------------------------------------------
     virtual bool
     AddModule(std::vector<llvm::StringRef> &path, Stream &error_stream) = 0;
+    
+    virtual void
+    ForEachMacro(std::function<bool (const std::string &)> handler) = 0;
 };
     
 }

Modified: lldb/trunk/source/Expression/ClangModulesDeclVendor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangModulesDeclVendor.cpp?rev=234922&r1=234921&r2=234922&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangModulesDeclVendor.cpp (original)
+++ lldb/trunk/source/Expression/ClangModulesDeclVendor.cpp Tue Apr 14 13:36:17 2015
@@ -62,13 +62,16 @@ namespace {
         
         virtual bool
         AddModule(std::vector<llvm::StringRef> &path,
-                  Stream &error_stream);
+                  Stream &error_stream) override;
         
         virtual uint32_t
         FindDecls (const ConstString &name,
                    bool append,
                    uint32_t max_matches,
-                   std::vector <clang::NamedDecl*> &decls);
+                   std::vector <clang::NamedDecl*> &decls) override;
+        
+        virtual void
+        ForEachMacro(std::function<bool (const std::string &)> handler) override;
         
         ~ClangModulesDeclVendorImpl();
         
@@ -253,6 +256,146 @@ ClangModulesDeclVendorImpl::FindDecls (c
     return num_matches;
 }
 
+void
+ClangModulesDeclVendorImpl::ForEachMacro(std::function<bool (const std::string &)> handler)
+{
+    
+    for (clang::Preprocessor::macro_iterator mi = m_compiler_instance->getPreprocessor().macro_begin(),
+                                             me = m_compiler_instance->getPreprocessor().macro_end();
+         mi != me;
+         ++mi)
+    {
+        if (mi->second->getKind() == clang::MacroDirective::MD_Define)
+        {            
+            std::string macro_expansion = "#define ";
+            macro_expansion.append(mi->first->getName().str().c_str());
+                
+            if (clang::MacroInfo *macro_info = mi->second->getMacroInfo())
+            {
+                if (macro_info->isFunctionLike())
+                {
+                    macro_expansion.append("(");
+                    
+                    bool first_arg = true;
+                    
+                    for (clang::MacroInfo::arg_iterator ai = macro_info->arg_begin(),
+                                                        ae = macro_info->arg_end();
+                         ai != ae;
+                         ++ai)
+                    {
+                        if (!first_arg)
+                        {
+                            macro_expansion.append(", ");
+                        }
+                        else
+                        {
+                            first_arg = false;
+                        }
+                        
+                        macro_expansion.append((*ai)->getName().str());
+                    }
+                    
+                    if (macro_info->isC99Varargs())
+                    {
+                        if (first_arg)
+                        {
+                            macro_expansion.append("...");
+                        }
+                        else
+                        {
+                            macro_expansion.append(", ...");
+                        }
+                    }
+                    else if (macro_info->isGNUVarargs())
+                    {
+                        macro_expansion.append("...");
+                    }
+                    
+                    macro_expansion.append(")");
+                }
+                
+                macro_expansion.append(" ");
+
+                bool first_token = true;
+                
+                for (clang::MacroInfo::tokens_iterator ti = macro_info->tokens_begin(),
+                     te = macro_info->tokens_end();
+                     ti != te;
+                     ++ti)
+                {
+                    if (!first_token)
+                    {
+                        macro_expansion.append(" ");
+                    }
+                    else
+                    {
+                        first_token = false;
+                    }
+                    
+                    if (ti->isLiteral())
+                    {
+                        if (const char *literal_data = ti->getLiteralData())
+                        {
+                            std::string token_str(literal_data, ti->getLength());
+                            macro_expansion.append(token_str);
+                        }
+                        else
+                        {
+                            bool invalid = false;
+                            const char *literal_source = m_compiler_instance->getSourceManager().getCharacterData(ti->getLocation(), &invalid);
+                            
+                            if (invalid)
+                            {
+#ifdef LLDB_CONFIGURATION_DEBUG
+                                assert(!"Unhandled token kind");
+#endif
+                                macro_expansion.append("<unknown literal value>");
+                            }
+                            else
+                            {
+                                macro_expansion.append(std::string(literal_source, ti->getLength()));
+                            }
+                        }
+                    }
+                    else if (const char *punctuator_spelling = clang::tok::getPunctuatorSpelling(ti->getKind()))
+                    {
+                        macro_expansion.append(punctuator_spelling);
+                    }
+                    else if (const char *keyword_spelling = clang::tok::getKeywordSpelling(ti->getKind()))
+                    {
+                        macro_expansion.append(keyword_spelling);
+                    }
+                    else
+                    {
+                        switch (ti->getKind())
+                        {
+                            case clang::tok::TokenKind::identifier:
+                                macro_expansion.append(ti->getIdentifierInfo()->getName().str());
+                                break;
+                            case clang::tok::TokenKind::raw_identifier:
+                                macro_expansion.append(ti->getRawIdentifier().str());
+                            default:
+                                macro_expansion.append(ti->getName());
+                                break;
+                        }
+                    }
+                }
+            }
+            else
+            {
+#ifdef LLDB_CONFIGURATION_DEBUG
+                assert(!"#define with no macro info");
+#endif
+            }
+            
+            if (handler(macro_expansion))
+            {
+                return;
+            }
+        }
+    }
+}
+
 ClangModulesDeclVendorImpl::~ClangModulesDeclVendorImpl()
 {
 }

Modified: lldb/trunk/source/Expression/ClangUserExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangUserExpression.cpp?rev=234922&r1=234921&r2=234922&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangUserExpression.cpp (original)
+++ lldb/trunk/source/Expression/ClangUserExpression.cpp Tue Apr 14 13:36:17 2015
@@ -26,6 +26,7 @@
 #include "lldb/Expression/ClangExpressionDeclMap.h"
 #include "lldb/Expression/ClangExpressionParser.h"
 #include "lldb/Expression/ClangFunction.h"
+#include "lldb/Expression/ClangModulesDeclVendor.h"
 #include "lldb/Expression/ClangPersistentVariables.h"
 #include "lldb/Expression/ClangUserExpression.h"
 #include "lldb/Expression/ExpressionSourceCode.h"
@@ -453,8 +454,19 @@ ClangUserExpression::Parse (Stream &erro
     ApplyObjcCastHack(m_expr_text);
     //ApplyUnicharHack(m_expr_text);
 
-    std::unique_ptr<ExpressionSourceCode> source_code (ExpressionSourceCode::CreateWrapped(m_expr_prefix.c_str(), m_expr_text.c_str()));
-
+    std::string prefix = m_expr_prefix;
+    
+    if (ClangModulesDeclVendor *decl_vendor = m_target->GetClangModulesDeclVendor())
+    {
+        decl_vendor->ForEachMacro([log, &prefix] (const std::string &expansion) -> bool {
+            prefix.append(expansion);
+            prefix.append("\n");
+            return false;
+        });
+    }
+    
+    std::unique_ptr<ExpressionSourceCode> source_code (ExpressionSourceCode::CreateWrapped(prefix.c_str(), m_expr_text.c_str()));
+    
     lldb::LanguageType lang_type;
 
     if (m_cplusplus)

Modified: lldb/trunk/test/lang/c/modules/TestCModules.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/c/modules/TestCModules.py?rev=234922&r1=234921&r2=234922&view=diff
==============================================================================
--- lldb/trunk/test/lang/c/modules/TestCModules.py (original)
+++ lldb/trunk/test/lang/c/modules/TestCModules.py Tue Apr 14 13:36:17 2015
@@ -73,6 +73,9 @@ class CModulesTestCase(TestBase):
 
         self.expect("expr *myFile", VARIABLES_DISPLAYED_CORRECTLY,
             substrs = ["a", "5", "b", "9"])
+
+        self.expect("expr MIN((uint64_t)2, (uint64_t)3)", VARIABLES_DISPLAYED_CORRECTLY,
+            substrs = ["uint64_t", "2"])
             
 if __name__ == '__main__':
     import atexit





More information about the lldb-commits mailing list