[英]How to know if an IntegerLiteral comes from a decimal or octal representation with Clang?
您可能知道, Clang
庫中的整數值由IntegerLiteral類處理。
但是,作為行動的問題,這兩項任務似乎沒有區別:
int i,j;
// i is assigned 42 with octal representation (052)
i = 052;
//j is assigned 42 with decimal representation (42)
j = 42;
AST-dump產生相同的樹:
|-DeclStmt 0x1cbc5b0 <line:2:2, col:9>
| |-VarDecl 0x1cbc4d0 <col:2, col:6> i 'int'
| `-VarDecl 0x1cbc540 <col:2, col:8> j 'int'
|-BinaryOperator 0x1cbc610 <line:4:2, col:6> 'int' lvalue '='
| |-DeclRefExpr 0x1cbc5c8 <col:2> 'int' lvalue Var 0x1cbc4d0 'i' 'int'
| `-IntegerLiteral 0x1cbc5f0 <col:6> 'int' 42
|-BinaryOperator 0x1cbc680 <line:5:2, col:6> 'int' lvalue '='
| |-DeclRefExpr 0x1cbc638 <col:2> 'int' lvalue Var 0x1cbc540 'j' 'int'
| `-IntegerLiteral 0x1cbc660 <col:6> 'int' 42
我想提出一些警告,因為使用八進制表示會被危險地誤解。 我可以區分Clang解析這兩種表示的方式嗎?
呼叫clang::Lexer::getSpelling
,它傳遞SourceLocation
您的IntegerLiteral
。 然后,您可以對八進制或您感興趣的任何其他拼寫屬性進行手動測試(例如,查找前導'0'
后跟數字)。 手動執行此檢查還可以讓您正確地獲得一些特殊情況 - 例如, 0
在技術上是八進制文字 ,但您可能不希望以這種方式對待它。
在無法實現理查德史密斯給出的答案后,我發現了一種非常討厭的方法(並且它不適用於MACROS),但萬一,這是我的(不完整但功能性)解決方案:
bool VisitIntegerLiteral(IntegerLiteral * intLiteral){
// Source Location of current int literal
SourceLocation loc = intLiteral->getLocation();
// Source manager associated
SourceManager &SM = _carrier->getSourceManager();
// Get first char and second char of the integer literal (getCharacterData returns the whole code from the SourceLocation until the end of code)
char first_char = SM.getCharacterData(loc,nullptr)[0];
char second_char= SM.getCharacterData(loc,nullptr)[1];
// If first character is 0
if(first_char == '0'){
// If second character is also a number
if(second_char == '1' || second_char == '2' || second_char == '3' || second_char == '4' || second_char == '5' || second_char == '6' || second_char == '7' || second_char == '8' || second_char == '9'){
cout << "This is an octal value" << endl;
}
}
return true;
}
如果整數常量以八進制或十進制方式給出,那么它只是一個句法事實。 編譯后,整數文字將轉換為相同的二進制數。 在正數的情況下,表示由標准精確地表示,是存儲的整數值的精確二進制表示。
因此,在任何情況下,源程序中的基數信息(八進制,十進制,十六進制)都不會存儲在任何地方,因此在執行環境中無法了解它的任何信息。
我同意Deduplicator的評論:你需要預處理源代碼本身以“看到”這些信息。
另一種替代方法可能是您不在第一種方法中使用int
值,而是使用字符串。
char *s_val1 = "052";
char *s_val2 = "42";
if (radix(s_val1) == 8) // You can write some function radix() to recognize the radix
printf("%s is octal", s_val1);
int val1 = octalstr_to_int(s_val1); // You can write some string-to-integer convertion functions
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.