2010-01-30 10 views
8

में टाइपपीफ को हल करना मैं मनमाने ढंग से सी ++ या सी परियोजनाओं में स्वचालित रूप से टाइपपीफ को हल करने का प्रयास कर रहा हूं।सी और सी ++

क्योंकि कुछ टाइपिफ़ाइफ़ सिस्टम हेडर फ़ाइलों (उदाहरण के लिए uint32) में परिभाषित किए गए हैं, इसलिए मैं वर्तमान में अपनी कोड फ़ाइलों पर जीसीसी प्रीप्रोसेसर चलाकर और टाइपप्रिफ के लिए प्रीप्रोसेस्ड फ़ाइलों को स्कैन करके इसे प्राप्त करने का प्रयास कर रहा हूं। तब मुझे प्रोजेक्ट की कोड फ़ाइलों में टाइपपीफ को प्रतिस्थापित करने में सक्षम होना चाहिए।

मुझे आश्चर्य है, अगर कोई दूसरा, शायद आसान तरीका है, तो मुझे याद आ रही है। क्या आप एक के बारे में सोच सकते हैं?

कारण, मैं ऐसा क्यों करना चाहता हूं: मैं विभिन्न उपकरणों के साथ सी/सी ++ परियोजनाओं से कोड मीट्रिक निकालने जा रहा हूं। मेट्रिक्स विधि-आधारित हैं। मेट्रिक्स निकालने के बाद, मुझे डेटा को मर्ज करना होगा, जो विभिन्न उपकरणों द्वारा उत्पादित किया जाता है। समस्या यह है कि उपकरण में से एक टाइपिफ़ को हल करता है और अन्य नहीं करते हैं। यदि पैरामीटर प्रकार के तरीकों के लिए टाइप किए गए टाइपपीफ हैं, तो मेरे पास अलग-अलग विधि-नामों के लिए मैट्रिक्स मैप किए गए हैं, जो वास्तव में स्रोत कोड में एक ही विधि का जिक्र कर रहे हैं। स्रोत कोड में इस विधि के

सोचें: int test(uint32 par1, int par2)
मेरी उपकरण चलाने के बाद मैं मैट्रिक्स, int test(uint32 par1, int par2) और मेरे कुछ मीट्रिक नामित int test(unsigned int par1, int par2) पर मैप किए जाते एक विधि को मैप किया है।

+5

क्या आप कुछ जानकारी भी दे सकते हैं कि आपको अपने कोड से इन टाइपिफ़ को हटाने की आवश्यकता क्यों है? शायद, यह समाधान का सुझाव देने में मदद करेगा। – Jay

उत्तर

5

यदि आपको यह पता लगाने की परवाह नहीं है कि उन्हें कहां परिभाषित किया गया है, तो आप objdump का उपयोग C++ प्रतीक तालिका को डंप करने के लिए कर सकते हैं जो टाइपपीफ को हल करता है।

lorien$ objdump --demangle --syms foo 

foo:  file format mach-o-i386 

SYMBOL TABLE: 
00001a24 g  1e SECT 01 0000 .text dyld_stub_binding_helper 
00001a38 g  1e SECT 01 0000 .text _dyld_func_lookup 
... 
00001c7c g  0f SECT 01 0080 .text foo::foo(char const*) 
... 

यह स्निपेट निम्नलिखित संरचना परिभाषा से है:

typedef char const* c_string; 
struct foo { 
    typedef c_string ntcstring; 
    foo(ntcstring s): buf(s) {} 
    std::string buf; 
}; 

यह आवश्यकता है कि आप सब कुछ संकलन और यह केवल जिसके परिणामस्वरूप निष्पादन में प्रतीकों दिखाएगा तो वहाँ कुछ सीमाएं हैं।दूसरा विकल्प है कि लिंकर एक प्रतीक मानचित्र डंप करें। जीएनयू टूल्स के लिए -Wl,-map और -Wl,name जोड़ें जहां name उत्पन्न करने के लिए फ़ाइल का नाम है (नोट देखें)। यह दृष्टिकोण नामों को विचलित नहीं करता है, लेकिन थोड़े से काम के साथ आप कंपाइलर के उलझन सम्मेलनों को इंजीनियर कर सकते हैं।

0x00001CBE 0x0000005E [ 2] __ZN3fooC2EPKc 
0x00001D1C 0x0000001A [ 2] __ZN3fooC1EPKc 

आप C++ ABI विनिर्देश का उपयोग कर इन को डिकोड कर सकते हैं: पिछले टुकड़ा से उत्पादन की तरह कुछ शामिल होंगे। एक बार जब आप इस काम के साथ सहज महसूस करते हैं, तो एबीआई के साथ mangling table शामिल हो जाता है। इस मामले में व्युत्पत्ति है:

<mangled-name>   ::= '_Z' <encoding> 
<encoding>    ::= <name> <bare-function-type> 
    <name>     ::= <nested-name> 
    <nested-name>  ::= 'N' <source-name> <ctor-dtor-name> 'E' 
     <source-name>  ::= <number> <identifier> 
     <ctor-dtor-name> ::= 'C2' # base object constructor 
    <bare-function-type> ::= <type>+ 
     <type>    ::= 'P' <type> # pointer to 
     <type>   ::= <cv-qualifier> <type> 
      <cv-qualifier> ::= 'K' # constant 
      <type>  ::= 'c' # character 

नोट: यह लग रहा है जीएनयू ld तर्क बदल जाता है की तरह है ताकि आप यह सुनिश्चित करें कि नक्शा फाइल पीढी के आदेशों -map हैं बनाने के लिए अपने स्थानीय पुस्तिका (man ld) भी देखना चाहें आपके संस्करण में filename। हाल के संस्करणों में, use -Wl,-M and redirect stdout to a file

+0

जब मैं अपने कंपाइलर को इस तरह चलाने की कोशिश करता हूं: 'g ++ foo.cpp -Wl, -map-wl, mapname' मुझे त्रुटि मिलती है '/ usr/bin/ld: अपरिचित इम्यूलेशन मोड: एपी समर्थित एम्यूलेशन: elf_i386 i386linux' । क्या मैं पैरामीटर का सही ढंग से उपयोग कर रहा हूं? (जी ++ संस्करण: 4.4.2 200 9 208 (प्रीरलीज), एलडी संस्करण: 2.20.0.20091101) – Customizer

+0

मैंने अपना जवाब अपडेट किया। मेरा स्थानीय संस्करण अभी भी 4.0.1 पर है और ऐसा लगता है कि तर्क बदल गए हैं। 'G ++ foo.cpp-wl, -M> foo.map' आज़माएं। –

+1

कार्यक्रम C++ filt का नाम नामों को बदनाम करने के लिए उपयोग किया जा सकता है। – Tronic

2

GCC-XML typedefs का समाधान करने में मदद कर सकते हैं, तो आप <Typedef> तत्वों के प्रकार-आईडी का पालन करने के लिए जब तक आप उन्हें एक <FundamentalType>, <Struct> या <Class> तत्व का संकल्प लिया होगा।

अपनी परियोजना में टाइपपीफ को बदलने के लिए आपके पास एक और मौलिक समस्या है हालांकि: आप केवल खोज और प्रतिस्थापन नहीं कर सकते क्योंकि आपको नामों के दायरे का सम्मान करना होगा - उदाहरण के बारे में सोचें फ़ंक्शन-स्थानीय टाइपपीफ, नेमस्पेस उपनाम या using निर्देश।

जो वास्तव में आप प्राप्त करने की कोशिश कर रहे हैं उसके आधार पर, एक बेहतर तरीका होना चाहिए।

अद्यतन: दरअसल, मेट्रिक्स डेटा को ठीक करने के दिए गए संदर्भ में, जीसीसी-एक्सएमएल का उपयोग कर टाइपनामों के प्रतिस्थापन को ठीक से काम करना चाहिए यदि यह आपके कोड-बेस का समर्थन करता है।

+0

मुझे यकीन नहीं है, लेकिन मुझे लगता है कि जीसीसी-एक्सएमएल वास्तव में सक्रिय रूप से विकसित नहीं हुआ है। आखिरी आधिकारिक संस्करण, वेबसाइट के मुताबिक, 2004 से है। और यदि मुझे सही याद है, तो सीवीएस संस्करण केवल जीसीसी के कुछ 3.x संस्करण पर आधारित है। मैं वास्तव में नहीं जानता, अगर यह मायने रखता है, हालांकि। हम्म, नामस्थान। ईमानदार होने के लिए अभी तक इसके बारे में सोचा नहीं था। इससे मामला जटिल हो जाता है ... – Customizer

+0

मैंने सोचा था कि आप स्रोत में प्रकारों को बदलना चाहते हैं, जो अधिक जटिल हो गया होगा। यदि आपको मेट्रिक्स डेटा को ठीक करने की आवश्यकता है, लेकिन स्रोत नहीं, तो gcc-xml पर्याप्त होना चाहिए यदि यह आपके कोड-बेस का समर्थन करता है। –

+0

दरअसल, मुझे लगता है कि परियोजनाएं, मैं विश्लेषण कर रहा हूं, सभी को एक जीसीसी बनाम 3.x द्वारा संकलित किया जाना चाहिए। तो यह काम कर सकता है। – Customizer

3

आप क्लैंग (एलएलवीएम सी/सी ++ कंपाइलर फ्रंट एंड) का उपयोग कोड को पार्स करने के लिए कर सकते हैं जो टाइपपीफ और यहां तक ​​कि मैक्रोज़ पर जानकारी को सुरक्षित रखता है। स्रोत कोड को एएसटी (अमूर्त वाक्यविन्यास पेड़) में पढ़ने के बाद डेटा पढ़ने के लिए यह बहुत अच्छा सी ++ एपीआई है। http://clang.llvm.org/

यदि आप इसके बजाय एक सरल प्रोग्राम की तलाश में हैं जो पहले से ही आपके लिए हल कर रहा है (क्लैंग प्रोग्रामिंग एपीआई के बजाय), मुझे लगता है कि आप भाग्य से बाहर हैं, क्योंकि मैंने कभी ऐसी चीज़ नहीं देखी है।

+0

मैंने सोचा कि clangs सी ++ पार्सर अभी तक पूरा नहीं हुआ है? –

+0

कोड जनरेशन काफी अधूरा है, लेकिन यह पहले से ही अधिकांश मानक पुस्तकालयों के साथ-साथ कई बाहरी पुस्तकालयों को भी संभाल सकता है। पार्सर अधिक पूर्ण है, लेकिन यहां तक ​​कि इसमें अभी भी कुछ चीजें नहीं हैं (इसलिए आप इसका उपयोग नहीं कर सकते हैं जैसे बूस्ट स्पिरिट.क्यूआई)। फिर भी, मुझे लगता है कि यह Customizer पूछ रहा है के लिए सबसे अच्छा उपलब्ध विकल्प हो सकता है। – Tronic

+0

एपीआई वास्तव में महान दिखता है। जब यह स्थिर हो गया तो मैं इसे आजमाने की कोशिश कर रहा हूं। –