1010#include " CppInterOp/CppInterOp.h"
1111
1212#include " Compatibility.h"
13+ #include " Sins.h" // for access to private members
1314
1415#include " clang/AST/Attrs.inc"
1516#include " clang/AST/CXXInheritance.h"
@@ -132,6 +133,9 @@ using namespace llvm;
132133struct InterpreterInfo {
133134 compat::Interpreter* Interpreter = nullptr ;
134135 bool isOwned = true ;
136+ // Store the list of builtin types.
137+ llvm::StringMap<QualType> BuiltinMap;
138+
135139 InterpreterInfo (compat::Interpreter* I, bool Owned)
136140 : Interpreter(I), isOwned(Owned) {}
137141
@@ -525,7 +529,7 @@ size_t SizeOf(TCppScope_t scope) {
525529 return 0 ;
526530}
527531
528- bool IsBuiltin (TCppType_t type) {
532+ bool IsBuiltin (TCppConstType_t type) {
529533 QualType Ty = QualType::getFromOpaquePtr (type);
530534 if (Ty->isBuiltinType () || Ty->isAnyComplexType ())
531535 return true ;
@@ -2004,69 +2008,109 @@ TCppType_t AddTypeQualifier(TCppType_t type, QualKind qual) {
20042008 return QT.getAsOpaquePtr ();
20052009}
20062010
2007- // Internal functions that are not needed outside the library are
2008- // encompassed in an anonymous namespace as follows. This function converts
2009- // from a string to the actual type. It is used in the GetType() function.
2010- namespace {
2011+ // Registers all permutations of a word set
2012+ static void RegisterPerms (llvm::StringMap<QualType>& Map, QualType QT,
2013+ llvm::SmallVectorImpl<llvm::StringRef>& Words) {
2014+ std::sort (Words.begin (), Words.end ());
2015+ do {
2016+ std::string Key;
2017+ for (size_t i = 0 ; i < Words.size (); ++i) {
2018+ if (i > 0 )
2019+ Key += ' ' ;
2020+ Key += Words[i].str ();
2021+ }
2022+ Map[Key] = QT;
2023+ } while (std::next_permutation (Words.begin (), Words.end ()));
2024+ }
2025+ ALLOW_ACCESS (ASTContext, Types, llvm::SmallVector<clang::Type*, 0 >);
2026+ static void PopulateBuiltinMap (ASTContext& Context) {
2027+ const PrintingPolicy Policy (Context.getLangOpts ());
2028+ auto & BuiltinMap = sInterpreters ->back ().BuiltinMap ;
2029+ const auto & Types = ACCESS (Context, Types);
2030+
2031+ for (clang::Type* T : Types) {
2032+ auto * BT = llvm::dyn_cast<BuiltinType>(T);
2033+ if (!BT || BT->isPlaceholderType ())
2034+ continue ;
2035+
2036+ QualType QT (BT, 0 );
2037+ std::string Name = QT.getAsString (Policy);
2038+ if (Name.empty () || Name[0 ] == ' <' )
2039+ continue ;
2040+
2041+ // Initial entry (e.g., "int", "unsigned long")
2042+ BuiltinMap[Name] = QT;
2043+
2044+ llvm::SmallVector<llvm::StringRef, 4 > Words;
2045+ llvm::StringRef (Name).split (Words, ' ' , -1 , false );
2046+
2047+ bool hasInt = false ;
2048+ bool hasSigned = false ;
2049+ bool hasUnsigned = false ;
2050+ bool hasChar = false ;
2051+ bool isModifiable = false ;
2052+
2053+ for (auto W : Words) {
2054+ if (W == " int" )
2055+ hasInt = true ;
2056+ else if (W == " signed" )
2057+ hasSigned = true ;
2058+ else if (W == " unsigned" )
2059+ hasUnsigned = true ;
2060+ else if (W == " char" )
2061+ hasChar = true ;
2062+
2063+ if (W == " long" || W == " short" || hasInt)
2064+ isModifiable = true ;
2065+ }
2066+
2067+ // Skip things like 'float' or 'double' that aren't combined
2068+ if (!isModifiable && !hasUnsigned && !hasSigned)
2069+ continue ;
2070+
2071+ // Register base permutations (e.g., "long long" or "unsigned int")
2072+ if (Words.size () > 1 )
2073+ RegisterPerms (BuiltinMap, QT, Words);
2074+
2075+ // Expansion: Add "int" suffix where missing (e.g., "short" -> "short int")
2076+ if (!hasInt && !hasChar) {
2077+ auto WithInt = Words;
2078+ WithInt.push_back (" int" );
2079+ RegisterPerms (BuiltinMap, QT, WithInt);
2080+
2081+ // If we are adding 'int', we should also try adding 'signed'
2082+ // to cover cases like "short" -> "signed short int"
2083+ if (!hasSigned && !hasUnsigned) {
2084+ auto WithBoth = WithInt;
2085+ WithBoth.push_back (" signed" );
2086+ RegisterPerms (BuiltinMap, QT, WithBoth);
2087+ }
2088+ }
2089+
2090+ // Expansion: Add "signed" prefix
2091+ // (e.g., "int" -> "signed int", "long" -> "signed long")
2092+ if (!hasSigned && !hasUnsigned) {
2093+ auto WithSigned = Words;
2094+ WithSigned.push_back (" signed" );
2095+ RegisterPerms (BuiltinMap, QT, WithSigned);
2096+ }
2097+ }
2098+
2099+ // Explicit global synonym
2100+ BuiltinMap[" signed" ] = Context.IntTy ;
2101+ BuiltinMap[" unsigned" ] = Context.UnsignedIntTy ;
2102+ }
20112103static QualType findBuiltinType (llvm::StringRef typeName, ASTContext& Context) {
2012- bool issigned = false ;
2013- bool isunsigned = false ;
2014- if (typeName.starts_with (" signed " )) {
2015- issigned = true ;
2016- typeName = StringRef (typeName.data () + 7 , typeName.size () - 7 );
2017- }
2018- if (!issigned && typeName.starts_with (" unsigned " )) {
2019- isunsigned = true ;
2020- typeName = StringRef (typeName.data () + 9 , typeName.size () - 9 );
2021- }
2022- if (typeName == " char" ) {
2023- if (isunsigned)
2024- return Context.UnsignedCharTy ;
2025- return Context.SignedCharTy ;
2026- }
2027- if (typeName == " short" ) {
2028- if (isunsigned)
2029- return Context.UnsignedShortTy ;
2030- return Context.ShortTy ;
2031- }
2032- if (typeName == " int" ) {
2033- if (isunsigned)
2034- return Context.UnsignedIntTy ;
2035- return Context.IntTy ;
2036- }
2037- if (typeName == " long" ) {
2038- if (isunsigned)
2039- return Context.UnsignedLongTy ;
2040- return Context.LongTy ;
2041- }
2042- if (typeName == " long long" ) {
2043- if (isunsigned)
2044- return Context.UnsignedLongLongTy ;
2045- return Context.LongLongTy ;
2046- }
2047- if (!issigned && !isunsigned) {
2048- if (typeName == " bool" )
2049- return Context.BoolTy ;
2050- if (typeName == " float" )
2051- return Context.FloatTy ;
2052- if (typeName == " double" )
2053- return Context.DoubleTy ;
2054- if (typeName == " long double" )
2055- return Context.LongDoubleTy ;
2056-
2057- if (typeName == " wchar_t" )
2058- return Context.WCharTy ;
2059- if (typeName == " char16_t" )
2060- return Context.Char16Ty ;
2061- if (typeName == " char32_t" )
2062- return Context.Char32Ty ;
2063- }
2064- /* Missing
2065- CanQualType WideCharTy; // Same as WCharTy in C++, integer type in C99.
2066- CanQualType WIntTy; // [C99 7.24.1], integer type unchanged by default
2067- promotions.
2068- */
2069- return QualType ();
2104+ llvm::StringMap<QualType>& BuiltinMap = sInterpreters ->back ().BuiltinMap ;
2105+ if (BuiltinMap.empty ())
2106+ PopulateBuiltinMap (Context);
2107+
2108+ // Fast Lookup
2109+ auto It = BuiltinMap.find (typeName);
2110+ if (It != BuiltinMap.end ())
2111+ return It->second ;
2112+
2113+ return QualType (); // Return null if not a builtin
20702114}
20712115static std::optional<QualType> GetTypeInternal (Decl* D) {
20722116 if (!D)
@@ -2084,7 +2128,6 @@ static std::optional<QualType> GetTypeInternal(Decl* D) {
20842128
20852129 return {};
20862130}
2087- } // namespace
20882131
20892132TCppType_t GetType (const std::string& name) {
20902133 QualType builtin = findBuiltinType (name, getASTContext ());
0 commit comments