Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(88)

Side by Side Diff: ppapi/tests/clang/print_names_and_sizes.cc

Issue 6014007: Improve documentation for the tools for generating size checks, based on comm... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ppapi/tests/clang/README ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Clang plugin which prints the names and sizes of all the top-level 5 // Clang plugin which prints the names and sizes of all the top-level
6 // structs, enums, and typedefs in the input file. 6 // structs, enums, and typedefs in the input file.
7 7
8 #include <cstdio> 8 #include <cstdio>
9 #include <cstring>
9 #include <string> 10 #include <string>
10 11
11 #include "clang/AST/AST.h" 12 #include "clang/AST/AST.h"
12 #include "clang/AST/ASTConsumer.h" 13 #include "clang/AST/ASTConsumer.h"
13 #include "clang/AST/CharUnits.h" 14 #include "clang/AST/CharUnits.h"
15 #include "clang/AST/Decl.h"
14 #include "clang/Basic/SourceManager.h" 16 #include "clang/Basic/SourceManager.h"
15 #include "clang/Basic/TargetInfo.h" 17 #include "clang/Basic/TargetInfo.h"
16 #include "clang/Frontend/CompilerInstance.h" 18 #include "clang/Frontend/CompilerInstance.h"
17 #include "clang/Frontend/FrontendPluginRegistry.h" 19 #include "clang/Frontend/FrontendPluginRegistry.h"
18 20
19 namespace { 21 namespace {
20 22
21 const char* const kTypedefName = "Typedef"; 23 const char* const kTypedefName = "Typedef";
22 const char* const kDelim = ","; 24 const char* const kDelim = ",";
23 const char* const kHasPointer = "HasPointer"; 25 const char* const kArchDependent = "ArchDependentSize";
24 const char* const kNoPointer = "NoPointer"; 26 const char* const kNotArchDependent = "NotArchDependentSize";
25 27
26 // This class consumes a Clang-parsed AST and prints out information about types 28 // This class consumes a Clang-parsed AST and prints out information about types
27 // defined in the global namespace. Specifically, for each type definition 29 // defined in the global namespace. Specifically, for each type definition
28 // encountered, it prints: 30 // encountered, it prints:
29 // "kind,name,size,has_pointer,source_file,first_line,last_line\n" 31 // "kind,name,size,arch_dependent,source_file,first_line,last_line\n"
30 // Where: 32 // Where:
31 // - kind: The Clang TypeClassName (Record, Enum, Typedef, Union, etc) 33 // - kind: The Clang TypeClassName (Record, Enum, Typedef, Union, etc)
32 // - name: The unmangled string name of the type. 34 // - name: The unmangled string name of the type.
33 // - size: The size in bytes of the type. 35 // - size: The size in bytes of the type.
34 // - has_pointer: 'HasPointer' if the type is or has a pointer. Otherwise, 36 // - arch_dependent: 'ArchDependentSize' if the type has architecture-dependent
35 // 'NoPointer'. 37 // size, NotArchDependentSize otherwise.
36 // - source_file: The source file in which the type is defined. 38 // - source_file: The source file in which the type is defined.
37 // - first_line: The first line of the definition (counting from 0). 39 // - first_line: The first line of the definition (counting from 0).
38 // - last_line: The last line of the definition (counting from 0). 40 // - last_line: The last line of the definition (counting from 0).
39 class PrintNamesAndSizesConsumer : public clang::ASTConsumer { 41 class PrintNamesAndSizesConsumer : public clang::ASTConsumer {
40 public: 42 public:
41 explicit PrintNamesAndSizesConsumer(clang::SourceManager* source_mgr) 43 explicit PrintNamesAndSizesConsumer(clang::SourceManager* source_mgr)
42 : source_manager_(source_mgr) {} 44 : source_manager_(source_mgr) {}
43 45
44 private: 46 private:
45 // SourceManager has information about source code locations, to help us know 47 // SourceManager has information about source code locations, to help us know
46 // where definitions appear. We do not own this pointer, so we must not 48 // where definitions appear. We do not own this pointer, so we must not
47 // delete it. 49 // delete it.
48 clang::SourceManager* source_manager_; 50 clang::SourceManager* source_manager_;
49 51
50 // Return true iff the type is a pointer or contains a pointer. This is 52 // Return true if the type contains types that differ in size between 32-bit
51 // important because these types may be different sizes on 32-bit vs 64-bit 53 // and 64-bit architectures. This is true for types that are typedefed to a
52 // platforms. Structs, enums, and unions that do NOT contain pointers are 54 // pointer, long, or unsigned long and also any types that contain an
55 // architecture-dependent type. Note that this is a bit overly restrictive;
56 // some unions may be consistent size on 32-bit and 64-bit architectures
57 // despite containing one of these types. But it's not an important enough
58 // issue to warrant coding the special case.
59 // Structs, enums, and unions that do NOT contain arch-dependent types are
53 // crafted to be the same size on 32-bit and 64-bit platforms by convention. 60 // crafted to be the same size on 32-bit and 64-bit platforms by convention.
54 bool HasPointer(const clang::Type& type) { 61 bool HasArchDependentSize(const clang::Type& type) {
55 if (type.isPointerType()) { 62 if (type.isPointerType()) {
56 return true; 63 return true;
64 } else if (const clang::BuiltinType* builtin =
65 dyn_cast<clang::BuiltinType>(&type)) {
66 if ((builtin->getKind() == clang::BuiltinType::Long) ||
67 (builtin->getKind() == clang::BuiltinType::ULong)) {
68 return true;
69 }
70 } else if (const clang::ArrayType* array =
71 dyn_cast<clang::ArrayType>(&type)) {
72 // If it's an array, it has architecture-dependent size if its elements
73 // do.
74 return HasArchDependentSize(*(array->getElementType().getTypePtr()));
75 } else if (const clang::TypedefType* typedef_type =
76 dyn_cast<clang::TypedefType>(&type)) {
77 return HasArchDependentSize(*(typedef_type->desugar().getTypePtr()));
57 } else if (const clang::RecordType* record = 78 } else if (const clang::RecordType* record =
58 dyn_cast<clang::RecordType>(&type)) { 79 dyn_cast<clang::RecordType>(&type)) {
59 // If it's a struct or union, iterate through the fields. If any of them 80 // If it's a struct or union, iterate through the fields. If any of them
60 // contain is or has a pointer, then we have one too. 81 // has architecture-dependent size, then we do too.
61 const clang::RecordDecl* decl = record->getDecl(); 82 const clang::RecordDecl* decl = record->getDecl();
62 clang::RecordDecl::field_iterator iter(decl->field_begin()); 83 clang::RecordDecl::field_iterator iter(decl->field_begin());
63 clang::RecordDecl::field_iterator end(decl->field_end()); 84 clang::RecordDecl::field_iterator end(decl->field_end());
64 for (; iter != end; ++iter) { 85 for (; iter != end; ++iter) {
65 if (HasPointer(*(iter->getType().getTypePtr()))) { 86 if (HasArchDependentSize(*(iter->getType().getTypePtr()))) {
66 return true; 87 return true;
67 } 88 }
68 } 89 }
69 // It's a struct or union, but contains no pointers. 90 // It's a struct or union, but contains no architecture-dependent members.
70 return false; 91 return false;
71 } 92 }
72 // It's not a pointer, a struct, or a union.
73 return false; 93 return false;
74 } 94 }
75 95
76 void PrintTypeInfo(const std::string& name, const clang::Type& type, 96 void PrintTypeInfo(const std::string& name, const clang::Type& type,
77 const std::string& kind, const clang::CharUnits& size, 97 const std::string& kind, const clang::CharUnits& size,
78 const clang::SourceLocation& begin_loc, 98 const clang::SourceLocation& begin_loc,
79 const clang::SourceLocation& end_loc) { 99 const clang::SourceLocation& end_loc) {
80 clang::PresumedLoc presumed_begin( 100 clang::PresumedLoc presumed_begin(
81 source_manager_->getPresumedLoc(begin_loc)); 101 source_manager_->getPresumedLoc(begin_loc));
82 clang::PresumedLoc presumed_end(source_manager_->getPresumedLoc(end_loc)); 102 clang::PresumedLoc presumed_end(source_manager_->getPresumedLoc(end_loc));
83 std::printf("%s,%s,%lu,%s,%s,%u,%u\n", 103 std::printf("%s,%s,%lu,%s,%s,%u,%u\n",
84 kind.c_str(), 104 kind.c_str(),
85 name.c_str(), 105 name.c_str(),
86 size.getQuantity(), 106 size.getQuantity(),
87 HasPointer(type) ? kHasPointer : kNoPointer, 107 HasArchDependentSize(type) ? kArchDependent : kNotArchDependent,
88 presumed_begin.getFilename(), 108 presumed_begin.getFilename(),
89 presumed_begin.getLine(), 109 presumed_begin.getLine(),
90 presumed_end.getLine()); 110 presumed_end.getLine());
91 } 111 }
92 112
93 // Virtual function to consume top-level declarations. For each one, we check 113 // Virtual function to consume top-level declarations. For each one, we check
94 // to see if it is a type definition. If it is, we print information about 114 // to see if it is a type definition. If it is, we print information about
95 // it. 115 // it.
96 virtual void HandleTopLevelDecl(clang::DeclGroupRef decl_group) { 116 virtual void HandleTopLevelDecl(clang::DeclGroupRef decl_group) {
97 clang::DeclGroupRef::iterator iter(decl_group.begin()); 117 clang::DeclGroupRef::iterator iter(decl_group.begin());
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 return true; 161 return true;
142 } 162 }
143 }; 163 };
144 164
145 } // namespace 165 } // namespace
146 166
147 static clang::FrontendPluginRegistry::Add<PrintNamesAndSizesAction> 167 static clang::FrontendPluginRegistry::Add<PrintNamesAndSizesAction>
148 X("PrintNamesAndSizes", 168 X("PrintNamesAndSizes",
149 "Print the names and sizes of classes, enums, and typedefs."); 169 "Print the names and sizes of classes, enums, and typedefs.");
150 170
OLDNEW
« no previous file with comments | « ppapi/tests/clang/README ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698