Index: ppapi/tests/clang/print_names_and_sizes.cc |
=================================================================== |
--- ppapi/tests/clang/print_names_and_sizes.cc (revision 69746) |
+++ ppapi/tests/clang/print_names_and_sizes.cc (working copy) |
@@ -6,11 +6,13 @@ |
// structs, enums, and typedefs in the input file. |
#include <cstdio> |
+#include <cstring> |
#include <string> |
#include "clang/AST/AST.h" |
#include "clang/AST/ASTConsumer.h" |
#include "clang/AST/CharUnits.h" |
+#include "clang/AST/Decl.h" |
#include "clang/Basic/SourceManager.h" |
#include "clang/Basic/TargetInfo.h" |
#include "clang/Frontend/CompilerInstance.h" |
@@ -20,19 +22,19 @@ |
const char* const kTypedefName = "Typedef"; |
const char* const kDelim = ","; |
-const char* const kHasPointer = "HasPointer"; |
-const char* const kNoPointer = "NoPointer"; |
+const char* const kArchDependent = "ArchDependentSize"; |
+const char* const kNotArchDependent = "NotArchDependentSize"; |
// This class consumes a Clang-parsed AST and prints out information about types |
// defined in the global namespace. Specifically, for each type definition |
// encountered, it prints: |
-// "kind,name,size,has_pointer,source_file,first_line,last_line\n" |
+// "kind,name,size,arch_dependent,source_file,first_line,last_line\n" |
// Where: |
// - kind: The Clang TypeClassName (Record, Enum, Typedef, Union, etc) |
// - name: The unmangled string name of the type. |
// - size: The size in bytes of the type. |
-// - has_pointer: 'HasPointer' if the type is or has a pointer. Otherwise, |
-// 'NoPointer'. |
+// - arch_dependent: 'ArchDependentSize' if the type has architecture-dependent |
+// size, NotArchDependentSize otherwise. |
// - source_file: The source file in which the type is defined. |
// - first_line: The first line of the definition (counting from 0). |
// - last_line: The last line of the definition (counting from 0). |
@@ -47,29 +49,47 @@ |
// delete it. |
clang::SourceManager* source_manager_; |
- // Return true iff the type is a pointer or contains a pointer. This is |
- // important because these types may be different sizes on 32-bit vs 64-bit |
- // platforms. Structs, enums, and unions that do NOT contain pointers are |
+ // Return true if the type contains types that differ in size between 32-bit |
+ // and 64-bit architectures. This is true for types that are typedefed to a |
+ // pointer, long, or unsigned long and also any types that contain an |
+ // architecture-dependent type. Note that this is a bit overly restrictive; |
+ // some unions may be consistent size on 32-bit and 64-bit architectures |
+ // despite containing one of these types. But it's not an important enough |
+ // issue to warrant coding the special case. |
+ // Structs, enums, and unions that do NOT contain arch-dependent types are |
// crafted to be the same size on 32-bit and 64-bit platforms by convention. |
- bool HasPointer(const clang::Type& type) { |
+ bool HasArchDependentSize(const clang::Type& type) { |
if (type.isPointerType()) { |
return true; |
+ } else if (const clang::BuiltinType* builtin = |
+ dyn_cast<clang::BuiltinType>(&type)) { |
+ if ((builtin->getKind() == clang::BuiltinType::Long) || |
+ (builtin->getKind() == clang::BuiltinType::ULong)) { |
+ return true; |
+ } |
+ } else if (const clang::ArrayType* array = |
+ dyn_cast<clang::ArrayType>(&type)) { |
+ // If it's an array, it has architecture-dependent size if its elements |
+ // do. |
+ return HasArchDependentSize(*(array->getElementType().getTypePtr())); |
+ } else if (const clang::TypedefType* typedef_type = |
+ dyn_cast<clang::TypedefType>(&type)) { |
+ return HasArchDependentSize(*(typedef_type->desugar().getTypePtr())); |
} else if (const clang::RecordType* record = |
dyn_cast<clang::RecordType>(&type)) { |
// If it's a struct or union, iterate through the fields. If any of them |
- // contain is or has a pointer, then we have one too. |
+ // has architecture-dependent size, then we do too. |
const clang::RecordDecl* decl = record->getDecl(); |
clang::RecordDecl::field_iterator iter(decl->field_begin()); |
clang::RecordDecl::field_iterator end(decl->field_end()); |
for (; iter != end; ++iter) { |
- if (HasPointer(*(iter->getType().getTypePtr()))) { |
+ if (HasArchDependentSize(*(iter->getType().getTypePtr()))) { |
return true; |
} |
} |
- // It's a struct or union, but contains no pointers. |
+ // It's a struct or union, but contains no architecture-dependent members. |
return false; |
} |
- // It's not a pointer, a struct, or a union. |
return false; |
} |
@@ -84,7 +104,7 @@ |
kind.c_str(), |
name.c_str(), |
size.getQuantity(), |
- HasPointer(type) ? kHasPointer : kNoPointer, |
+ HasArchDependentSize(type) ? kArchDependent : kNotArchDependent, |
presumed_begin.getFilename(), |
presumed_begin.getLine(), |
presumed_end.getLine()); |