Bu bir SO sorusu olarak başladı, ancak oldukça alışılmadık olduğunu ve web sitelerindeki gerçek açıklamaya dayanarak, programcılara daha uygun olabileceğini fark ettim. Çünkü sorunun çok fazla kavramsal ağırlığı var.
Ben öğrenme edilmiştir clang LibTooling ve bir de, bir dost bir şekilde, kod bütün "işinin zor" açığa kapasitesine sahip çok güçlü bir araçtır anlamsal ya tahmin ederek olursa ve bunlarla. Clang kodunuzu derlemek, o zaman çınlama olduğunu belli bu kodu içine her karakterin semantik hakkında.
Şimdi bir anlığına geri çekmeme izin verin.
Biri C ++ şablon meta programlamasına dahil olduğunda (ve özellikle de şablonların ötesinde korkunç makrolar da olsa zeki bölgelere girerken) ortaya çıkan birçok pratik problem vardır. Dürüst olmak gerekirse, ben dahil birçok programcı için, şablonların sıradan kullanımlarının birçoğu da biraz korkutucu.
İyi bir örnek derleme zamanı dizeleri olurdu sanırım . Bu şu anda bir yıldan daha eski bir soru, ama şu anda C ++ 'ın sadece ölümlüler için bunu kolaylaştırdığı açık. Bu seçeneklere bakmak benim için bulantıyı tetiklemek için yeterli olmasa da, yazılımım için sahip olduğum her türlü fantezi uygulamaya uyacak şekilde büyülü, maksimum verimli makine kodu üretme konusunda emin olmamı sağlıyor.
Yani, bununla yüzleşelim, millet, teller oldukça basit ve basit. Bazılarımız sadece belirli dizeleri "pişmiş" olan makine kodunu yaymak için uygun bir yol istiyoruz. C ++ kodumuzda.
Kaynak kodun soyut sözdizimi ağacını (AST) gösteren ve basit bir özel C ++ uygulamasının, AST'deki Rewriter
her şeyin zengin bir anlamsal nesne yönelimli modelinin yanı sıra ham kaynak kodunu (kullanarak ) doğru ve güvenilir bir şekilde değiştirmesine izin veren clang ve LibTooling girin . Bir çok şeyi halleder. Makro açılımlarını bilir ve bu zincirleri takip etmenizi sağlar. Evet, kaynaktan kaynağa kod dönüştürme veya çeviri hakkında konuşuyorum.
Buradaki temel tezim, clang'ın artık C ++ yazılımımız için ideal özel önişlemci aşamaları olarak işlev görebilen yürütülebilir dosyalar oluşturmamızı sağlaması ve bu metaprogramlama aşamalarını C ++ ile uygulayabilmemiz. Biz sadece bu aşamanın geçerli C ++ kodu olan girdi alması ve çıktı olarak daha geçerli C ++ kodu üretmesi gerçeği ile kısıtlanıyoruz. Ayrıca, derleme sisteminizin uyguladığı diğer kısıtlamalar ne olursa olsun.
Girdi, en azından geçerli C ++ koduna çok yakın olmalı, çünkü clang derleyici ön uçudur ve sadece API ile yaratıcılık yapıyoruz. Kullanılacak yeni sözdizimini tanımlamak için herhangi bir hüküm olup olmadığını bilmiyorum, ancak bunu yapmak için düzgün bir şekilde ayrıştırma ve clang projesine ekleme yollarını geliştirmemiz gerekiyor. Daha fazlasını beklemek clang projesinde kapsam dışı olan bir şeylere sahip olmaktır.
Problem değil. Bazı op-olmayan makro fonksiyonlarının bu görevi yerine getirebileceğini hayal ediyorum.
Ne açıklamak için bakmak başka bir yolu, kaynak kodun AST (clang ve API sayesinde) dilde kullanılabilir daha sınırlı araçları kullanarak uygulamak yerine, C ++ çalışma zamanı kullanarak metaprogramming yapıları uygulamaktır. Bu da derleme performansının net faydalarına sahiptir (şablon-ağır başlıklar derleme, bunları ne sıklıkta kullandığınıza orantılı olarak yavaşlar. Derlenmiş birçok öğe daha sonra dikkatlice eşleştirilir ve bağlayıcı tarafından atılır).
Bununla birlikte, bu, oluşturma işlemine ek bir veya iki adım ekleme ve aynı zamanda aracımızın bir parçası olarak (itirafla) biraz daha ayrıntılı bir yazılım yazma gereksinimi (ancak en azından basit çalışma zamanı C ++) gereksinimindedir. .
Resmin tamamı bu değil. Temel dil özellikleri ile son derece zor veya imkansız kod üretmekten daha büyük bir işlevsellik alanı olduğundan eminim. C ++ 'da bir şablon veya makro veya her ikisinin çılgın bir kombinasyonunu yazabilirsiniz, ancak bir clang aracında , semantik içeriğe tam erişime sahipken , çalışma zamanında C ++ ile elde edebileceğiniz HERHANGİ bir şekilde sınıfları ve işlevleri değiştirebilirsiniz , şablon ve makrolara ve diğer her şeye ek olarak.
Herkesin bunu neden yapmadığını merak ediyorum. Clang'ın bu işlevselliği çok yeni mi ve hiç kimse clang AST'sinin devasa sınıf hiyerarşisine aşina değil mi? Bu olamaz.
Belki de bunun zorluğunu biraz küçümsüyorum, ancak bir clang aracıyla "derleme zamanı dize manipülasyonu" yapmak neredeyse cezai basittir. Bu ayrıntılı, ama delicesine açık. Tek gereken, gerçek gerçek std::string
işlemlerle eşleşen bir grup işlemeyen makro işlevidir . Clang eklentisi, ilgili tüm op-op makro çağrılarını getirerek uygular ve işlemleri dizelerle gerçekleştirir. Bu araç daha sonra oluşturma işleminin bir parçası olarak eklenir. Derleme sırasında, bu işlem dışı makro işlev çağrıları otomatik olarak sonuçlarına göre değerlendirilir ve daha sonra programda eski düz derleme zamanı dizeleri olarak geri eklenir. Program daha sonra her zamanki gibi derlenebilir. Aslında sonuçta ortaya çıkan bu program, C ++ 11'i destekleyen yeni ve süslü bir derleyici gerektirmeyen sonuç olarak çok daha taşınabilir.