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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: ppapi/tests/clang/print_names_and_sizes.cc
===================================================================
--- ppapi/tests/clang/print_names_and_sizes.cc (revision 0)
+++ ppapi/tests/clang/print_names_and_sizes.cc (revision 0)
@@ -0,0 +1,150 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Clang plugin which prints the names and sizes of all the top-level
+// structs, enums, and typedefs in the input file.
+
+#include <cstdio>
+#include <string>
+
+#include "clang/AST/AST.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/CharUnits.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/FrontendPluginRegistry.h"
+
+namespace {
+
+const char* const kTypedefName = "Typedef";
+const char* const kDelim = ",";
+const char* const kHasPointer = "HasPointer";
+const char* const kNoPointer = "NoPointer";
+
+// 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"
+// 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'.
+// - 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
+// - 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
+// - last_line: The last line of the definition (counting from 0).
+class PrintNamesAndSizesConsumer : public clang::ASTConsumer {
+ public:
+ explicit PrintNamesAndSizesConsumer(clang::SourceManager* source_mgr)
+ : source_manager_(source_mgr) {}
+
+ private:
+ // SourceManager has information about source code locations, to help us know
+ // where definitions appear. We do not own this pointer, so we must not
+ // delete it.
+ clang::SourceManager* source_manager_;
+
+ // 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 {
+ // 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
+ // crafted to be the same size on 32-bit and 64-bit platforms by convention.
+ bool HasPointer(const clang::Type& type) {
+ if (type.isPointerType()) {
+ return true;
+ } 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.
David Springer 2010/12/13 21:23:08 "...contain is or has a pointer..." -- ?
+ 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()))) {
+ return true;
+ }
+ }
+ // It's a struct or union, but contains no pointers.
+ return false;
+ }
+ // It's not a pointer, a struct, or a union.
+ return false;
+ }
+
+ void PrintTypeInfo(const std::string& name, const clang::Type& type,
+ const std::string& kind, const clang::CharUnits& size,
+ const clang::SourceLocation& begin_loc,
+ const clang::SourceLocation& end_loc) {
+ clang::PresumedLoc presumed_begin(
+ source_manager_->getPresumedLoc(begin_loc));
+ clang::PresumedLoc presumed_end(source_manager_->getPresumedLoc(end_loc));
+ std::printf("%s,%s,%lu,%s,%s,%u,%u\n",
+ kind.c_str(),
+ name.c_str(),
+ size.getQuantity(),
+ HasPointer(type) ? kHasPointer : kNoPointer,
+ presumed_begin.getFilename(),
+ presumed_begin.getLine(),
+ presumed_end.getLine());
+ }
+
+ // Virtual function to consume top-level declarations. For each one, we check
+ // to see if it is a type definition. If it is, we print information about
+ // it.
+ virtual void HandleTopLevelDecl(clang::DeclGroupRef decl_group) {
+ clang::DeclGroupRef::iterator iter(decl_group.begin());
+ clang::DeclGroupRef::iterator the_end(decl_group.end());
+ for (; iter != the_end; ++iter) {
+ const clang::Decl *decl = *iter;
+ if (const clang::TypeDecl* type_decl = dyn_cast<clang::TypeDecl>(decl)) {
+ std::string name(type_decl->getNameAsString());
+ clang::SourceLocation start_loc = type_decl->getLocStart();
+ clang::SourceLocation end_loc = type_decl->getLocEnd();
+ // TagDecl covers structs, enums, unions, and classes.
+ if (const clang::TagDecl* tag = dyn_cast<clang::TagDecl>(type_decl)) {
+ // Only print out info when we find the definition; ignore forward
+ // references.
+ if (tag->isDefinition()) {
+ clang::Type* type = type_decl->getTypeForDecl();
+ clang::CharUnits size =
+ tag->getASTContext().getTypeSizeInChars(type);
+ PrintTypeInfo(name, *type, type->getTypeClassName(), size,
+ start_loc, end_loc);
+ }
+ } else if (const clang::TypedefDecl* td =
+ dyn_cast<clang::TypedefDecl>(type_decl)) {
+ clang::Type* type = td->getUnderlyingType().getTypePtr();
+ clang::CharUnits size = td->getASTContext().getTypeSizeInChars(type);
+ PrintTypeInfo(name, *type, kTypedefName, size, start_loc, end_loc);
+ }
+ }
+ }
+ }
+};
+
+class PrintNamesAndSizesAction : public clang::PluginASTAction {
+ public:
+ PrintNamesAndSizesAction() {}
+
+ private:
+ virtual clang::ASTConsumer *CreateASTConsumer(
+ clang::CompilerInstance &instance, llvm::StringRef /*input_file*/) {
+ return new PrintNamesAndSizesConsumer(
+ &(instance.getDiagnostics().getSourceManager()));
+ }
+
+ // We don't accept any arguments, but ParseArgs is pure-virtual.
+ virtual bool ParseArgs(const clang::CompilerInstance& /*instance*/,
+ const std::vector<std::string>& /*args*/) {
+ return true;
+ }
+};
+
+} // namespace
+
+static clang::FrontendPluginRegistry::Add<PrintNamesAndSizesAction>
+X("PrintNamesAndSizes",
+ "Print the names and sizes of classes, enums, and typedefs.");
+
Property changes on: ppapi/tests/clang/print_names_and_sizes.cc
___________________________________________________________________
Added: svn:eol-style
+ LF

Powered by Google App Engine
This is Rietveld 408576698