| Index: ppapi/tests/clang/print_names_and_sizes.cc
|
| ===================================================================
|
| --- ppapi/tests/clang/print_names_and_sizes.cc (revision 69190)
|
| +++ ppapi/tests/clang/print_names_and_sizes.cc (working copy)
|
| @@ -1,150 +0,0 @@
|
| -// 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.
|
| -// - first_line: The first line of the definition (counting from 0).
|
| -// - 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
|
| - // 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.
|
| - 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.");
|
| -
|
|
|