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

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

Issue 5730003: Add the following Clang plugins:... (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
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 // Clang plugin which prints the names and sizes of all the top-level
6 // structs, enums, and typedefs in the input file.
7
8 #include <cstdio>
9 #include <string>
10
11 #include "clang/AST/AST.h"
12 #include "clang/AST/ASTConsumer.h"
13 #include "clang/AST/CharUnits.h"
14 #include "clang/Basic/SourceManager.h"
15 #include "clang/Basic/TargetInfo.h"
16 #include "clang/Frontend/CompilerInstance.h"
17 #include "clang/Frontend/FrontendPluginRegistry.h"
18
19 namespace {
20
21 const char* const kTypedefName = "Typedef";
22 const char* const kDelim = ",";
23 const char* const kHasPointer = "HasPointer";
24 const char* const kNoPointer = "NoPointer";
25
26 // This class consumes a Clang-parsed AST and prints out information about types
27 // defined in the global namespace. Specifically, for each type definition
28 // encountered, it prints:
29 // "kind,name,size,has_pointer,source_file,first_line,last_line\n"
30 // Where:
31 // - kind: The Clang TypeClassName (Record, Enum, Typedef, Union, etc)
32 // - name: The unmangled string name of the type.
33 // - size: The size in bytes of the type.
34 // - has_pointer: 'HasPointer' if the type is or has a pointer. Otherwise,
35 // 'NoPointer'.
36 // - source_file: The source file in which the type is defined.
David Springer 2010/12/13 21:23:08 Is this a full POSIX path? An OS-specific path? O
37 // - first_line: The first line of the definition (counting from 0).
David Springer 2010/12/13 21:23:08 "first line number" - just to be clear that you wa
38 // - last_line: The last line of the definition (counting from 0).
39 class PrintNamesAndSizesConsumer : public clang::ASTConsumer {
40 public:
41 explicit PrintNamesAndSizesConsumer(clang::SourceManager* source_mgr)
42 : source_manager_(source_mgr) {}
43
44 private:
45 // 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
47 // delete it.
48 clang::SourceManager* source_manager_;
49
50 // Return true iff the type is a pointer or contains a pointer. This is
David Springer 2010/12/13 21:23:08 "or contains a pointer" - as in: struct PP_Var {
51 // important because these types may be different sizes on 32-bit vs 64-bit
52 // platforms. Structs, enums, and unions that do NOT contain pointers are
53 // crafted to be the same size on 32-bit and 64-bit platforms by convention.
54 bool HasPointer(const clang::Type& type) {
55 if (type.isPointerType()) {
56 return true;
57 } else if (const clang::RecordType* record =
58 dyn_cast<clang::RecordType>(&type)) {
59 // 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.
David Springer 2010/12/13 21:23:08 "...contain is or has a pointer..." -- ?
61 const clang::RecordDecl* decl = record->getDecl();
62 clang::RecordDecl::field_iterator iter(decl->field_begin());
63 clang::RecordDecl::field_iterator end(decl->field_end());
64 for (; iter != end; ++iter) {
65 if (HasPointer(*(iter->getType().getTypePtr()))) {
66 return true;
67 }
68 }
69 // It's a struct or union, but contains no pointers.
70 return false;
71 }
72 // It's not a pointer, a struct, or a union.
73 return false;
74 }
75
76 void PrintTypeInfo(const std::string& name, const clang::Type& type,
77 const std::string& kind, const clang::CharUnits& size,
78 const clang::SourceLocation& begin_loc,
79 const clang::SourceLocation& end_loc) {
80 clang::PresumedLoc presumed_begin(
81 source_manager_->getPresumedLoc(begin_loc));
82 clang::PresumedLoc presumed_end(source_manager_->getPresumedLoc(end_loc));
83 std::printf("%s,%s,%lu,%s,%s,%u,%u\n",
84 kind.c_str(),
85 name.c_str(),
86 size.getQuantity(),
87 HasPointer(type) ? kHasPointer : kNoPointer,
88 presumed_begin.getFilename(),
89 presumed_begin.getLine(),
90 presumed_end.getLine());
91 }
92
93 // 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
95 // it.
96 virtual void HandleTopLevelDecl(clang::DeclGroupRef decl_group) {
97 clang::DeclGroupRef::iterator iter(decl_group.begin());
98 clang::DeclGroupRef::iterator the_end(decl_group.end());
99 for (; iter != the_end; ++iter) {
100 const clang::Decl *decl = *iter;
101 if (const clang::TypeDecl* type_decl = dyn_cast<clang::TypeDecl>(decl)) {
102 std::string name(type_decl->getNameAsString());
103 clang::SourceLocation start_loc = type_decl->getLocStart();
104 clang::SourceLocation end_loc = type_decl->getLocEnd();
105 // TagDecl covers structs, enums, unions, and classes.
106 if (const clang::TagDecl* tag = dyn_cast<clang::TagDecl>(type_decl)) {
107 // Only print out info when we find the definition; ignore forward
108 // references.
109 if (tag->isDefinition()) {
110 clang::Type* type = type_decl->getTypeForDecl();
111 clang::CharUnits size =
112 tag->getASTContext().getTypeSizeInChars(type);
113 PrintTypeInfo(name, *type, type->getTypeClassName(), size,
114 start_loc, end_loc);
115 }
116 } else if (const clang::TypedefDecl* td =
117 dyn_cast<clang::TypedefDecl>(type_decl)) {
118 clang::Type* type = td->getUnderlyingType().getTypePtr();
119 clang::CharUnits size = td->getASTContext().getTypeSizeInChars(type);
120 PrintTypeInfo(name, *type, kTypedefName, size, start_loc, end_loc);
121 }
122 }
123 }
124 }
125 };
126
127 class PrintNamesAndSizesAction : public clang::PluginASTAction {
128 public:
129 PrintNamesAndSizesAction() {}
130
131 private:
132 virtual clang::ASTConsumer *CreateASTConsumer(
133 clang::CompilerInstance &instance, llvm::StringRef /*input_file*/) {
134 return new PrintNamesAndSizesConsumer(
135 &(instance.getDiagnostics().getSourceManager()));
136 }
137
138 // We don't accept any arguments, but ParseArgs is pure-virtual.
139 virtual bool ParseArgs(const clang::CompilerInstance& /*instance*/,
140 const std::vector<std::string>& /*args*/) {
141 return true;
142 }
143 };
144
145 } // namespace
146
147 static clang::FrontendPluginRegistry::Add<PrintNamesAndSizesAction>
148 X("PrintNamesAndSizes",
149 "Print the names and sizes of classes, enums, and typedefs.");
150
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698