Stage two of getting CFE top correct.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@39734 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/AST/AST.h b/include/clang/AST/AST.h
new file mode 100644
index 0000000..a185692
--- /dev/null
+++ b/include/clang/AST/AST.h
@@ -0,0 +1,24 @@
+//===--- AST.h - "Umbrella" header for AST library --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the interface to the AST classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_AST_H
+#define LLVM_CLANG_AST_AST_H
+
+// This header exports all AST interfaces.
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/StmtVisitor.h"
+
+#endif
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
new file mode 100644
index 0000000..759940d
--- /dev/null
+++ b/include/clang/AST/ASTContext.h
@@ -0,0 +1,128 @@
+//===--- ASTContext.h - Context to hold long-lived AST nodes ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ASTContext interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_ASTCONTEXT_H
+#define LLVM_CLANG_AST_ASTCONTEXT_H
+
+#include "clang/AST/Builtins.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/Expr.h"
+#include <vector>
+
+namespace clang {
+ class TargetInfo;
+
+/// ASTContext - This class holds long-lived AST nodes (such as types and
+/// decls) that can be referred to throughout the semantic analysis of a file.
+class ASTContext {
+ std::vector<Type*> Types;
+ llvm::FoldingSet<ComplexType> ComplexTypes;
+ llvm::FoldingSet<PointerType> PointerTypes;
+ llvm::FoldingSet<ReferenceType> ReferenceTypes;
+ llvm::FoldingSet<ArrayType> ArrayTypes;
+ llvm::FoldingSet<VectorType> VectorTypes;
+ llvm::FoldingSet<FunctionTypeNoProto> FunctionTypeNoProtos;
+ llvm::FoldingSet<FunctionTypeProto> FunctionTypeProtos;
+public:
+ TargetInfo &Target;
+ Builtin::Context BuiltinInfo;
+
+ // Builtin Types.
+ QualType VoidTy;
+ QualType BoolTy;
+ QualType CharTy;
+ QualType SignedCharTy, ShortTy, IntTy, LongTy, LongLongTy;
+ QualType UnsignedCharTy, UnsignedShortTy, UnsignedIntTy, UnsignedLongTy;
+ QualType UnsignedLongLongTy;
+ QualType FloatTy, DoubleTy, LongDoubleTy;
+ QualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy;
+
+ ASTContext(TargetInfo &t, IdentifierTable &idents) : Target(t) {
+ InitBuiltinTypes();
+ BuiltinInfo.InitializeBuiltins(idents, Target);
+ }
+ ~ASTContext();
+
+ void PrintStats() const;
+
+ /// getComplexType - Return the uniqued reference to the type for a complex
+ /// number with the specified element type.
+ QualType getComplexType(QualType T);
+
+ /// getPointerType - Return the uniqued reference to the type for a pointer to
+ /// the specified type.
+ QualType getPointerType(QualType T);
+
+ /// getReferenceType - Return the uniqued reference to the type for a
+ /// reference to the specified type.
+ QualType getReferenceType(QualType T);
+
+ /// getArrayType - Return the unique reference to the type for an array of the
+ /// specified element type.
+ QualType getArrayType(QualType EltTy, ArrayType::ArraySizeModifier ASM,
+ unsigned EltTypeQuals, Expr *NumElts);
+
+ /// convertToVectorType - Return the unique reference to a vector type of
+ /// the specified element type and size. VectorType can be a pointer, array,
+ /// function, or built-in type (i.e. _Bool, integer, or float).
+ QualType convertToVectorType(QualType VectorType, unsigned NumElts);
+
+ /// getFunctionTypeNoProto - Return a K&R style C function type like 'int()'.
+ ///
+ QualType getFunctionTypeNoProto(QualType ResultTy);
+
+ /// getFunctionType - Return a normal function type with a typed argument
+ /// list. isVariadic indicates whether the argument list includes '...'.
+ QualType getFunctionType(QualType ResultTy, QualType *ArgArray,
+ unsigned NumArgs, bool isVariadic);
+
+ /// getTypedefType - Return the unique reference to the type for the
+ /// specified typename decl.
+ QualType getTypedefType(TypedefDecl *Decl);
+
+ /// getTagDeclType - Return the unique reference to the type for the
+ /// specified TagDecl (struct/union/class/enum) decl.
+ QualType getTagDeclType(TagDecl *Decl);
+
+ /// getSizeType - Return the unique type for "size_t" (C99 7.17), defined
+ /// in <stddef.h>. The sizeof operator requires this (C99 6.5.3.4p4).
+ QualType getSizeType() const;
+
+ /// getIntegerBitwidth - Return the bitwidth of the specified integer type
+ /// according to the target. 'Loc' specifies the source location that
+ /// requires evaluation of this property.
+ unsigned getIntegerBitwidth(QualType T, SourceLocation Loc);
+
+ // maxIntegerType - Returns the highest ranked integer type. Handles 3
+ // different type combos: unsigned/unsigned, signed/signed, signed/unsigned.
+ static QualType maxIntegerType(QualType lhs, QualType rhs);
+
+ // maxFloatingType - Returns the highest ranked float type. Both input
+ // types are required to be floats.
+ static QualType maxFloatingType(QualType lt, QualType rt);
+
+ // maxComplexType - Returns the highest ranked complex type. Handles 3
+ // different type combos: complex/complex, complex/float, float/complex.
+ QualType maxComplexType(QualType lt, QualType rt) const;
+
+private:
+ ASTContext(const ASTContext&); // DO NOT IMPLEMENT
+ void operator=(const ASTContext&); // DO NOT IMPLEMENT
+
+ void InitBuiltinTypes();
+ void InitBuiltinType(QualType &R, BuiltinType::Kind K);
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/AST/Builtins.def b/include/clang/AST/Builtins.def
new file mode 100644
index 0000000..97431da
--- /dev/null
+++ b/include/clang/AST/Builtins.def
@@ -0,0 +1,53 @@
+//===--- Builtins.def - Builtin function info database ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the standard builtin function database. Users of this file
+// must define the BUILTIN macro to make use of this information.
+//
+//===----------------------------------------------------------------------===//
+
+// FIXME: this needs to be the full list supported by GCC. Right now, I'm just
+// adding stuff on demand.
+//
+// FIXME: This should really be a .td file, but that requires modifying tblgen.
+// Perhaps tblgen should have plugins.
+
+// The first value provided to the macro specifies the function name of the
+// builtin, and results in a clang::builtin::BIXX enum value for XX.
+
+// The second value provided to the macro specifies the type of the function
+// (result value, then each argument) as follows:
+// v -> void
+// c -> char
+// s -> short
+// i -> int
+// f -> float
+// d -> double
+// . -> "...". This may only occur at the end of the function list.
+//
+// Types maybe prefixed with the following modifiers:
+// L -> long (e.g. Li for 'long int')
+// LL -> long long
+// S -> signed
+// U -> unsigned
+
+// The third value provided to the macro specifies information about attributes
+// of the function. Currently we have:
+// n -> nothrow
+// c -> const
+
+BUILTIN(__builtin_inf , "d" , "nc")
+BUILTIN(__builtin_inff , "f" , "nc")
+BUILTIN(__builtin_infl , "Ld" , "nc")
+BUILTIN(__builtin_fabs , "dd" , "nc")
+BUILTIN(__builtin_fabsf, "ff" , "nc")
+BUILTIN(__builtin_fabsl, "LdLd", "nc")
+BUILTIN(__builtin_constant_p, "UsUs", "nc")
+
+#undef BUILTIN
diff --git a/include/clang/AST/Builtins.h b/include/clang/AST/Builtins.h
new file mode 100644
index 0000000..682031f
--- /dev/null
+++ b/include/clang/AST/Builtins.h
@@ -0,0 +1,72 @@
+//===--- Builtins.h - Builtin function header -------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines enum values for all the target-independent builtin
+// functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_BUILTINS_H
+#define LLVM_CLANG_AST_BUILTINS_H
+
+#include <cstring>
+
+namespace clang {
+ class TargetInfo;
+ class IdentifierTable;
+ class ASTContext;
+ class QualType;
+
+namespace Builtin {
+enum ID {
+ NotBuiltin = 0, // This is not a builtin function.
+#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+#include "clang/AST/Builtins.def"
+ FirstTSBuiltin
+};
+
+struct Info {
+ const char *Name, *Type, *Attributes;
+
+ bool operator==(const Info &RHS) const {
+ return !strcmp(Name, RHS.Name) &&
+ !strcmp(Type, RHS.Type) &&
+ !strcmp(Attributes, RHS.Attributes);
+ }
+ bool operator!=(const Info &RHS) const { return !(*this == RHS); }
+};
+
+/// Builtin::Context - This holds information about target-independent and
+/// target-specific builtins, allowing easy queries by clients.
+class Context {
+ const Info *TSRecords;
+ unsigned NumTSRecords;
+public:
+ Context() : TSRecords(0), NumTSRecords(0) {}
+
+ /// InitializeBuiltins - Mark the identifiers for all the builtins with their
+ /// appropriate builtin ID # and mark any non-portable builtin identifiers as
+ /// such.
+ void InitializeBuiltins(IdentifierTable &Table, const TargetInfo &Target);
+
+ /// Builtin::GetName - Return the identifier name for the specified builtin,
+ /// e.g. "__builtin_abs".
+ const char *GetName(unsigned ID) const {
+ return GetRecord(ID).Name;
+ }
+
+ /// GetBuiltinType - Return the type for the specified builtin.
+ QualType GetBuiltinType(unsigned ID, ASTContext &Context) const;
+private:
+ const Info &GetRecord(unsigned ID) const;
+};
+
+}
+} // end namespace clang
+#endif
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
new file mode 100644
index 0000000..2d3b01d
--- /dev/null
+++ b/include/clang/AST/Decl.h
@@ -0,0 +1,442 @@
+//===--- Decl.h - Classes for representing declarations ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the Decl interface and subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_DECL_H
+#define LLVM_CLANG_AST_DECL_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "clang/AST/Type.h"
+#include "llvm/ADT/APSInt.h"
+
+namespace clang {
+class IdentifierInfo;
+class Expr;
+class Stmt;
+class FunctionDecl;
+
+
+/// Decl - This represents one declaration (or definition), e.g. a variable,
+/// typedef, function, struct, etc.
+///
+class Decl {
+public:
+ enum Kind {
+ // Concrete sub-classes of ValueDecl
+ Function, BlockVariable, FileVariable, ParmVariable, EnumConstant,
+ // Concrete sub-classes of TypeDecl
+ Typedef, Struct, Union, Class, Enum,
+ // Concrete sub-class of Decl
+ Field
+ };
+
+ /// IdentifierNamespace - According to C99 6.2.3, there are four namespaces,
+ /// labels, tags, members and ordinary identifiers.
+ enum IdentifierNamespace {
+ IDNS_Label,
+ IDNS_Tag,
+ IDNS_Member,
+ IDNS_Ordinary
+ };
+private:
+ /// DeclKind - This indicates which class this is.
+ Kind DeclKind;
+
+ /// Loc - The location that this decl.
+ SourceLocation Loc;
+
+ /// Identifier - The identifier for this declaration (e.g. the name for the
+ /// variable, the tag for a struct).
+ IdentifierInfo *Identifier;
+
+ /// When this decl is in scope while parsing, the Next field contains a
+ /// pointer to the shadowed decl of the same name. When the scope is popped,
+ /// Decls are relinked onto a containing decl object.
+ ///
+ Decl *Next;
+
+ /// NextDeclarator - If this decl was part of a multi-declarator declaration,
+ /// such as "int X, Y, *Z;" this indicates Decl for the next declarator.
+ Decl *NextDeclarator;
+
+protected:
+ Decl(Kind DK, SourceLocation L, IdentifierInfo *Id, Decl *NextDecl)
+ : DeclKind(DK), Loc(L), Identifier(Id), Next(0), NextDeclarator(NextDecl) {
+ if (Decl::CollectingStats()) addDeclKind(DK);
+ }
+ virtual ~Decl();
+
+public:
+ IdentifierInfo *getIdentifier() const { return Identifier; }
+ SourceLocation getLocation() const { return Loc; }
+ void setLocation(SourceLocation L) { Loc = L; }
+ const char *getName() const;
+
+ Kind getKind() const { return DeclKind; }
+ Decl *getNext() const { return Next; }
+ void setNext(Decl *N) { Next = N; }
+
+ /// getNextDeclarator - If this decl was part of a multi-declarator
+ /// declaration, such as "int X, Y, *Z;" this returns the decl for the next
+ /// declarator. Otherwise it returns null.
+ Decl *getNextDeclarator() { return NextDeclarator; }
+ const Decl *getNextDeclarator() const { return NextDeclarator; }
+ void setNextDeclarator(Decl *N) { NextDeclarator = N; }
+
+ IdentifierNamespace getIdentifierNamespace() const {
+ switch (DeclKind) {
+ default: assert(0 && "Unknown decl kind!");
+ case Typedef:
+ case Function:
+ case BlockVariable:
+ case FileVariable:
+ case ParmVariable:
+ case EnumConstant:
+ return IDNS_Ordinary;
+ case Struct:
+ case Union:
+ case Class:
+ case Enum:
+ return IDNS_Tag;
+ }
+ }
+ // global temp stats (until we have a per-module visitor)
+ static void addDeclKind(const Kind k);
+ static bool CollectingStats(bool enable=false);
+ static void PrintStats();
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *) { return true; }
+};
+
+/// ValueDecl - Represent the declaration of a variable (in which case it is
+/// an lvalue) a function (in which case it is a function designator) or
+/// an enum constant.
+class ValueDecl : public Decl {
+ QualType DeclType;
+protected:
+ ValueDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T,
+ Decl *PrevDecl) : Decl(DK, L, Id, PrevDecl), DeclType(T) {}
+public:
+ QualType getType() const { return DeclType; }
+ void setType(QualType newType) { DeclType = newType; }
+ QualType getCanonicalType() const { return DeclType.getCanonicalType(); }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) {
+ return D->getKind() >= Function && D->getKind() <= EnumConstant;
+ }
+ static bool classof(const ValueDecl *D) { return true; }
+};
+
+/// VarDecl - An instance of this class is created to represent a variable
+/// declaration or definition.
+class VarDecl : public ValueDecl {
+public:
+ enum StorageClass {
+ None, Extern, Static, Auto, Register
+ };
+ StorageClass getStorageClass() const { return SClass; }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) {
+ return D->getKind() >= BlockVariable && D->getKind() <= ParmVariable;
+ }
+ static bool classof(const VarDecl *D) { return true; }
+protected:
+ VarDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T,
+ StorageClass SC, Decl *PrevDecl)
+ : ValueDecl(DK, L, Id, T, PrevDecl) { SClass = SC; }
+private:
+ StorageClass SClass;
+ // TODO: Initializer.
+};
+
+/// BlockVarDecl - Represent a local variable declaration.
+class BlockVarDecl : public VarDecl {
+public:
+ BlockVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S,
+ Decl *PrevDecl)
+ : VarDecl(BlockVariable, L, Id, T, S, PrevDecl) {}
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return D->getKind() == BlockVariable; }
+ static bool classof(const BlockVarDecl *D) { return true; }
+};
+
+/// FileVarDecl - Represent a file scoped variable declaration. This
+/// will allow us to reason about external variable declarations and tentative
+/// definitions (C99 6.9.2p2) using our type system (without storing a
+/// pointer to the decl's scope, which is transient).
+class FileVarDecl : public VarDecl {
+public:
+ FileVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S,
+ Decl *PrevDecl)
+ : VarDecl(FileVariable, L, Id, T, S, PrevDecl) {}
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return D->getKind() == FileVariable; }
+ static bool classof(const FileVarDecl *D) { return true; }
+};
+
+/// ParmVarDecl - Represent a parameter to a function.
+class ParmVarDecl : public VarDecl {
+public:
+ ParmVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S,
+ Decl *PrevDecl)
+ : VarDecl(ParmVariable, L, Id, T, S, PrevDecl) {}
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return D->getKind() == ParmVariable; }
+ static bool classof(const ParmVarDecl *D) { return true; }
+};
+
+/// FunctionDecl - An instance of this class is created to represent a function
+/// declaration or definition.
+class FunctionDecl : public ValueDecl {
+public:
+ enum StorageClass {
+ None, Extern, Static
+ };
+ FunctionDecl(SourceLocation L, IdentifierInfo *Id, QualType T,
+ StorageClass S = None, Decl *PrevDecl)
+ : ValueDecl(Function, L, Id, T, PrevDecl),
+ ParamInfo(0), Body(0), DeclChain(0), SClass(S) {}
+ virtual ~FunctionDecl();
+
+ Stmt *getBody() const { return Body; }
+ void setBody(Stmt *B) { Body = B; }
+
+ Decl *getDeclChain() const { return DeclChain; }
+ void setDeclChain(Decl *D) { DeclChain = D; }
+
+ unsigned getNumParams() const;
+ const ParmVarDecl *getParamDecl(unsigned i) const {
+ assert(i < getNumParams() && "Illegal param #");
+ return ParamInfo[i];
+ }
+ ParmVarDecl *getParamDecl(unsigned i) {
+ assert(i < getNumParams() && "Illegal param #");
+ return ParamInfo[i];
+ }
+ void setParams(ParmVarDecl **NewParamInfo, unsigned NumParams);
+
+ QualType getResultType() const {
+ return cast<FunctionType>(getType())->getResultType();
+ }
+ StorageClass getStorageClass() const { return SClass; }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return D->getKind() == Function; }
+ static bool classof(const FunctionDecl *D) { return true; }
+private:
+ /// ParamInfo - new[]'d array of pointers to VarDecls for the formal
+ /// parameters of this function. This is null if a prototype or if there are
+ /// no formals. TODO: we could allocate this space immediately after the
+ /// FunctionDecl object to save an allocation like FunctionType does.
+ ParmVarDecl **ParamInfo;
+
+ Stmt *Body; // Null if a prototype.
+
+ /// DeclChain - Linked list of declarations that are defined inside this
+ /// function.
+ Decl *DeclChain;
+
+ StorageClass SClass;
+};
+
+
+/// FieldDecl - An instance of this class is created by Sema::ParseField to
+/// represent a member of a struct/union/class.
+class FieldDecl : public Decl {
+ QualType DeclType;
+public:
+ FieldDecl(SourceLocation L, IdentifierInfo *Id, QualType T, Decl *PrevDecl)
+ : Decl(Field, L, Id, PrevDecl), DeclType(T) {}
+
+ QualType getType() const { return DeclType; }
+ QualType getCanonicalType() const { return DeclType.getCanonicalType(); }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) {
+ return D->getKind() == Field;
+ }
+ static bool classof(const FieldDecl *D) { return true; }
+};
+
+/// EnumConstantDecl - An instance of this object exists for each enum constant
+/// that is defined. For example, in "enum X {a,b}", each of a/b are
+/// EnumConstantDecl's, X is an instance of EnumDecl, and the type of a/b is a
+/// TagType for the X EnumDecl.
+class EnumConstantDecl : public ValueDecl {
+ Expr *Init; // an integer constant expression
+ llvm::APSInt Val; // The value.
+public:
+ EnumConstantDecl(SourceLocation L, IdentifierInfo *Id, QualType T, Expr *E,
+ const llvm::APSInt &V, Decl *PrevDecl)
+ : ValueDecl(EnumConstant, L, Id, T, PrevDecl), Init(E), Val(V) {}
+
+ const Expr *getInitExpr() const { return Init; }
+ Expr *getInitExpr() { return Init; }
+ const llvm::APSInt &getInitVal() const { return Val; }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) {
+ return D->getKind() == EnumConstant;
+ }
+ static bool classof(const EnumConstantDecl *D) { return true; }
+};
+
+
+/// TypeDecl - Represents a declaration of a type.
+///
+class TypeDecl : public Decl {
+ /// TypeForDecl - This indicates the Type object that represents this
+ /// TypeDecl. It is a cache maintained by ASTContext::getTypedefType and
+ /// ASTContext::getTagDeclType.
+ Type *TypeForDecl;
+ friend class ASTContext;
+protected:
+ TypeDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, Decl *PrevDecl)
+ : Decl(DK, L, Id, PrevDecl), TypeForDecl(0) {}
+public:
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) {
+ return D->getKind() >= Typedef && D->getKind() <= Enum;
+ }
+ static bool classof(const TypeDecl *D) { return true; }
+};
+
+
+class TypedefDecl : public TypeDecl {
+ /// UnderlyingType - This is the type the typedef is set to.
+ QualType UnderlyingType;
+public:
+ TypedefDecl(SourceLocation L, IdentifierInfo *Id, QualType T, Decl *PrevDecl)
+ : TypeDecl(Typedef, L, Id, PrevDecl), UnderlyingType(T) {}
+
+ QualType getUnderlyingType() const { return UnderlyingType; }
+ void setUnderlyingType(QualType newType) { UnderlyingType = newType; }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) { return D->getKind() == Typedef; }
+ static bool classof(const TypedefDecl *D) { return true; }
+};
+
+
+/// TagDecl - Represents the declaration of a struct/union/class/enum.
+class TagDecl : public TypeDecl {
+ /// IsDefinition - True if this is a definition ("struct foo {};"), false if
+ /// it is a declaration ("struct foo;").
+ bool IsDefinition : 1;
+protected:
+ TagDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, Decl *PrevDecl)
+ : TypeDecl(DK, L, Id, PrevDecl) {
+ IsDefinition = false;
+ }
+public:
+
+ /// isDefinition - Return true if this decl has its body specified.
+ bool isDefinition() const {
+ return IsDefinition;
+ }
+
+ const char *getKindName() const {
+ switch (getKind()) {
+ default: assert(0 && "Unknown TagDecl!");
+ case Struct: return "struct";
+ case Union: return "union";
+ case Class: return "class";
+ case Enum: return "enum";
+ }
+ }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const Decl *D) {
+ return D->getKind() == Struct || D->getKind() == Union ||
+ D->getKind() == Class || D->getKind() == Enum;
+ }
+ static bool classof(const TagDecl *D) { return true; }
+protected:
+ void setDefinition(bool V) { IsDefinition = V; }
+};
+
+/// EnumDecl - Represents an enum. As an extension, we allow forward-declared
+/// enums.
+class EnumDecl : public TagDecl {
+ /// ElementList - this is a linked list of EnumConstantDecl's which are linked
+ /// together through their getNextDeclarator pointers.
+ EnumConstantDecl *ElementList;
+public:
+ EnumDecl(SourceLocation L, IdentifierInfo *Id, Decl *PrevDecl)
+ : TagDecl(Enum, L, Id, PrevDecl) {
+ ElementList = 0;
+ }
+
+ /// defineElements - When created, EnumDecl correspond to a forward declared
+ /// enum. This method is used to mark the decl as being defined, with the
+ /// specified list of enums.
+ void defineElements(EnumConstantDecl *ListHead) {
+ assert(!isDefinition() && "Cannot redefine enums!");
+ ElementList = ListHead;
+ setDefinition(true);
+ }
+
+ static bool classof(const Decl *D) {
+ return D->getKind() == Enum;
+ }
+ static bool classof(const EnumDecl *D) { return true; }
+};
+
+
+/// RecordDecl - Represents a struct/union/class.
+class RecordDecl : public TagDecl {
+ /// HasFlexibleArrayMember - This is true if this struct ends with a flexible
+ /// array member (e.g. int X[]) or if this union contains a struct that does.
+ /// If so, this cannot be contained in arrays or other structs as a member.
+ bool HasFlexibleArrayMember : 1;
+
+ /// Members/NumMembers - This is a new[]'d array of pointers to Decls.
+ FieldDecl **Members; // Null if not defined.
+ int NumMembers; // -1 if not defined.
+public:
+ RecordDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, Decl *PrevDecl)
+ : TagDecl(DK, L, Id, PrevDecl) {
+ HasFlexibleArrayMember = false;
+ assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!");
+ Members = 0;
+ NumMembers = -1;
+ }
+
+ bool hasFlexibleArrayMember() const { return HasFlexibleArrayMember; }
+ void setHasFlexibleArrayMember(bool V) { HasFlexibleArrayMember = V; }
+
+ /// defineBody - When created, RecordDecl's correspond to a forward declared
+ /// record. This method is used to mark the decl as being defined, with the
+ /// specified contents.
+ void defineBody(FieldDecl **Members, unsigned numMembers);
+
+ /// getMember - If the member doesn't exist, or there are no members, this
+ /// function will return 0;
+ FieldDecl *getMember(IdentifierInfo *name);
+
+ static bool classof(const Decl *D) {
+ return D->getKind() == Struct || D->getKind() == Union ||
+ D->getKind() == Class;
+ }
+ static bool classof(const RecordDecl *D) { return true; }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
new file mode 100644
index 0000000..fcf179e
--- /dev/null
+++ b/include/clang/AST/Expr.h
@@ -0,0 +1,596 @@
+//===--- Expr.h - Classes for representing expressions ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the Expr interface and subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_EXPR_H
+#define LLVM_CLANG_AST_EXPR_H
+
+#include "clang/AST/Stmt.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/APSInt.h"
+
+namespace clang {
+ class IdentifierInfo;
+ class Decl;
+
+/// Expr - This represents one expression. Note that Expr's are subclasses of
+/// Stmt. This allows an expression to be transparently used any place a Stmt
+/// is required.
+///
+class Expr : public Stmt {
+ QualType TR;
+protected:
+ Expr(StmtClass SC, QualType T) : Stmt(SC), TR(T) {}
+ ~Expr() {}
+public:
+ QualType getType() const { return TR; }
+
+ /// SourceLocation tokens are not useful in isolation - they are low level
+ /// value objects created/interpreted by SourceManager. We assume AST
+ /// clients will have a pointer to the respective SourceManager.
+ virtual SourceRange getSourceRange() const = 0;
+ SourceLocation getLocStart() const { return getSourceRange().Begin(); }
+ SourceLocation getLocEnd() const { return getSourceRange().End(); }
+
+ /// getExprLoc - Return the preferred location for the arrow when diagnosing
+ /// a problem with a generic expression.
+ virtual SourceLocation getExprLoc() const { return getLocStart(); }
+
+ /// hasLocalSideEffect - Return true if this immediate expression has side
+ /// effects, not counting any sub-expressions.
+ bool hasLocalSideEffect() const;
+
+ /// isLvalue - C99 6.3.2.1: an lvalue is an expression with an object type or
+ /// incomplete type other than void. Nonarray expressions that can be lvalues:
+ /// - name, where name must be a variable
+ /// - e[i]
+ /// - (e), where e must be an lvalue
+ /// - e.name, where e must be an lvalue
+ /// - e->name
+ /// - *e, the type of e cannot be a function type
+ /// - string-constant
+ ///
+ enum isLvalueResult {
+ LV_Valid,
+ LV_NotObjectType,
+ LV_IncompleteVoidType,
+ LV_InvalidExpression
+ };
+ isLvalueResult isLvalue();
+
+ /// isModifiableLvalue - C99 6.3.2.1: an lvalue that does not have array type,
+ /// does not have an incomplete type, does not have a const-qualified type,
+ /// and if it is a structure or union, does not have any member (including,
+ /// recursively, any member or element of all contained aggregates or unions)
+ /// with a const-qualified type.
+ enum isModifiableLvalueResult {
+ MLV_Valid,
+ MLV_NotObjectType,
+ MLV_IncompleteVoidType,
+ MLV_InvalidExpression,
+ MLV_IncompleteType,
+ MLV_ConstQualified,
+ MLV_ArrayType
+ };
+ isModifiableLvalueResult isModifiableLvalue();
+
+ bool isNullPointerConstant() const;
+
+ /// isIntegerConstantExpr - Return true if this expression is a valid integer
+ /// constant expression, and, if so, return its value in Result. If not a
+ /// valid i-c-e, return false and fill in Loc (if specified) with the location
+ /// of the invalid expression.
+ bool isIntegerConstantExpr(llvm::APSInt &Result, SourceLocation *Loc = 0,
+ bool isEvaluated = true) const;
+ bool isIntegerConstantExpr(SourceLocation *Loc = 0) const {
+ llvm::APSInt X(32);
+ return isIntegerConstantExpr(X, Loc);
+ }
+
+ virtual void visit(StmtVisitor &Visitor);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() >= firstExprConstant &&
+ T->getStmtClass() <= lastExprConstant;
+ }
+ static bool classof(const Expr *) { return true; }
+};
+
+//===----------------------------------------------------------------------===//
+// Primary Expressions.
+//===----------------------------------------------------------------------===//
+
+/// DeclRefExpr - [C99 6.5.1p2] - A reference to a declared variable, function,
+/// enum, etc.
+class DeclRefExpr : public Expr {
+ Decl *D; // a ValueDecl or EnumConstantDecl
+ SourceLocation Loc;
+public:
+ DeclRefExpr(Decl *d, QualType t, SourceLocation l) :
+ Expr(DeclRefExprClass, t), D(d), Loc(l) {}
+
+ Decl *getDecl() { return D; }
+ const Decl *getDecl() const { return D; }
+ virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
+
+
+ virtual void visit(StmtVisitor &Visitor);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == DeclRefExprClass;
+ }
+ static bool classof(const DeclRefExpr *) { return true; }
+};
+
+class IntegerLiteral : public Expr {
+ llvm::APInt Value;
+ SourceLocation Loc;
+public:
+ // type should be IntTy, LongTy, LongLongTy, UnsignedIntTy, UnsignedLongTy,
+ // or UnsignedLongLongTy
+ IntegerLiteral(const llvm::APInt &V, QualType type, SourceLocation l)
+ : Expr(IntegerLiteralClass, type), Value(V), Loc(l) {
+ assert(type->isIntegerType() && "Illegal type in IntegerLiteral");
+ }
+ const llvm::APInt &getValue() const { return Value; }
+ virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
+
+ virtual void visit(StmtVisitor &Visitor);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == IntegerLiteralClass;
+ }
+ static bool classof(const IntegerLiteral *) { return true; }
+};
+
+class CharacterLiteral : public Expr {
+ unsigned Value;
+ SourceLocation Loc;
+public:
+ // type should be IntTy
+ CharacterLiteral(unsigned value, QualType type, SourceLocation l)
+ : Expr(CharacterLiteralClass, type), Value(value), Loc(l) {
+ }
+ virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
+
+ unsigned getValue() const { return Value; }
+
+ virtual void visit(StmtVisitor &Visitor);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CharacterLiteralClass;
+ }
+ static bool classof(const CharacterLiteral *) { return true; }
+};
+
+class FloatingLiteral : public Expr {
+ float Value; // FIXME
+ SourceLocation Loc;
+public:
+ FloatingLiteral(float value, QualType type, SourceLocation l)
+ : Expr(FloatingLiteralClass, type), Value(value), Loc(l) {}
+
+ float getValue() const { return Value; }
+
+ virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
+
+ virtual void visit(StmtVisitor &Visitor);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == FloatingLiteralClass;
+ }
+ static bool classof(const FloatingLiteral *) { return true; }
+};
+
+class StringLiteral : public Expr {
+ const char *StrData;
+ unsigned ByteLength;
+ bool IsWide;
+ // if the StringLiteral was composed using token pasting, both locations
+ // are needed. If not (the common case), firstTokLoc == lastTokLoc.
+ // FIXME: if space becomes an issue, we should create a sub-class.
+ SourceLocation firstTokLoc, lastTokLoc;
+public:
+ StringLiteral(const char *strData, unsigned byteLength, bool Wide,
+ QualType t, SourceLocation b, SourceLocation e);
+ virtual ~StringLiteral();
+
+ const char *getStrData() const { return StrData; }
+ unsigned getByteLength() const { return ByteLength; }
+ bool isWide() const { return IsWide; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(firstTokLoc,lastTokLoc);
+ }
+ virtual void visit(StmtVisitor &Visitor);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == StringLiteralClass;
+ }
+ static bool classof(const StringLiteral *) { return true; }
+};
+
+/// ParenExpr - This represents a parethesized expression, e.g. "(1)". This
+/// AST node is only formed if full location information is requested.
+class ParenExpr : public Expr {
+ SourceLocation L, R;
+ Expr *Val;
+public:
+ ParenExpr(SourceLocation l, SourceLocation r, Expr *val)
+ : Expr(ParenExprClass, val->getType()), L(l), R(r), Val(val) {}
+
+ const Expr *getSubExpr() const { return Val; }
+ Expr *getSubExpr() { return Val; }
+ SourceRange getSourceRange() const { return SourceRange(L, R); }
+
+ virtual void visit(StmtVisitor &Visitor);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ParenExprClass;
+ }
+ static bool classof(const ParenExpr *) { return true; }
+};
+
+
+/// UnaryOperator - This represents the unary-expression's (except sizeof of
+/// types), the postinc/postdec operators from postfix-expression, and various
+/// extensions.
+class UnaryOperator : public Expr {
+public:
+ enum Opcode {
+ PostInc, PostDec, // [C99 6.5.2.4] Postfix increment and decrement operators
+ PreInc, PreDec, // [C99 6.5.3.1] Prefix increment and decrement operators.
+ AddrOf, Deref, // [C99 6.5.3.2] Address and indirection operators.
+ Plus, Minus, // [C99 6.5.3.3] Unary arithmetic operators.
+ Not, LNot, // [C99 6.5.3.3] Unary arithmetic operators.
+ SizeOf, AlignOf, // [C99 6.5.3.4] Sizeof (expr, not type) operator.
+ Real, Imag, // "__real expr"/"__imag expr" Extension.
+ Extension // __extension__ marker.
+ };
+private:
+ Expr *Val;
+ Opcode Opc;
+ SourceLocation Loc;
+public:
+
+ UnaryOperator(Expr *input, Opcode opc, QualType type, SourceLocation l)
+ : Expr(UnaryOperatorClass, type), Val(input), Opc(opc), Loc(l) {}
+
+ Opcode getOpcode() const { return Opc; }
+ Expr *getSubExpr() const { return Val; }
+
+ /// getOperatorLoc - Return the location of the operator.
+ SourceLocation getOperatorLoc() const { return Loc; }
+
+ /// isPostfix - Return true if this is a postfix operation, like x++.
+ static bool isPostfix(Opcode Op);
+
+ bool isPostfix() const { return isPostfix(Opc); }
+ bool isIncrementDecrementOp() const { return Opc>=PostInc && Opc<=PreDec; }
+ bool isSizeOfAlignOfOp() const { return Opc == SizeOf || Opc == AlignOf; }
+ static bool isArithmeticOp(Opcode Op) { return Op >= Plus && Op <= LNot; }
+
+ /// getDecl - a recursive routine that derives the base decl for an
+ /// expression. For example, it will return the declaration for "s" from
+ /// the following complex expression "s.zz[2].bb.vv".
+ static bool isAddressable(Expr *e);
+
+ /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
+ /// corresponds to, e.g. "sizeof" or "[pre]++"
+ static const char *getOpcodeStr(Opcode Op);
+
+ virtual SourceRange getSourceRange() const {
+ if (isPostfix())
+ return SourceRange(Val->getLocStart(), Loc);
+ else
+ return SourceRange(Loc, Val->getLocEnd());
+ }
+ virtual SourceLocation getExprLoc() const { return Loc; }
+
+ virtual void visit(StmtVisitor &Visitor);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == UnaryOperatorClass;
+ }
+ static bool classof(const UnaryOperator *) { return true; }
+};
+
+/// SizeOfAlignOfTypeExpr - [C99 6.5.3.4] - This is only for sizeof/alignof of
+/// *types*. sizeof(expr) is handled by UnaryOperator.
+class SizeOfAlignOfTypeExpr : public Expr {
+ bool isSizeof; // true if sizeof, false if alignof.
+ QualType Ty;
+ SourceLocation OpLoc, RParenLoc;
+public:
+ SizeOfAlignOfTypeExpr(bool issizeof, QualType argType, QualType resultType,
+ SourceLocation op, SourceLocation rp) :
+ Expr(SizeOfAlignOfTypeExprClass, resultType),
+ isSizeof(issizeof), Ty(argType), OpLoc(op), RParenLoc(rp) {}
+
+ bool isSizeOf() const { return isSizeof; }
+ QualType getArgumentType() const { return Ty; }
+ SourceRange getSourceRange() const { return SourceRange(OpLoc, RParenLoc); }
+
+ virtual void visit(StmtVisitor &Visitor);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == SizeOfAlignOfTypeExprClass;
+ }
+ static bool classof(const SizeOfAlignOfTypeExpr *) { return true; }
+};
+
+//===----------------------------------------------------------------------===//
+// Postfix Operators.
+//===----------------------------------------------------------------------===//
+
+/// ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
+class ArraySubscriptExpr : public Expr {
+ Expr *Base, *Idx;
+ SourceLocation RBracketLoc;
+public:
+ ArraySubscriptExpr(Expr *base, Expr *idx, QualType t,
+ SourceLocation rbracketloc) :
+ Expr(ArraySubscriptExprClass, t),
+ Base(base), Idx(idx), RBracketLoc(rbracketloc) {}
+
+ Expr *getBase() { return Base; }
+ const Expr *getBase() const { return Base; }
+ Expr *getIdx() { return Idx; }
+ const Expr *getIdx() const { return Idx; }
+
+ SourceRange getSourceRange() const {
+ return SourceRange(Base->getLocStart(), RBracketLoc);
+ }
+ virtual SourceLocation getExprLoc() const { return RBracketLoc; }
+
+ virtual void visit(StmtVisitor &Visitor);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ArraySubscriptExprClass;
+ }
+ static bool classof(const ArraySubscriptExpr *) { return true; }
+};
+
+
+/// CallExpr - [C99 6.5.2.2] Function Calls.
+///
+class CallExpr : public Expr {
+ Expr *Fn;
+ Expr **Args;
+ unsigned NumArgs;
+ SourceLocation RParenLoc;
+public:
+ CallExpr(Expr *fn, Expr **args, unsigned numargs, QualType t,
+ SourceLocation rparenloc);
+ ~CallExpr() {
+ delete [] Args;
+ }
+
+ const Expr *getCallee() const { return Fn; }
+ Expr *getCallee() { return Fn; }
+
+ /// getNumArgs - Return the number of actual arguments to this call.
+ ///
+ unsigned getNumArgs() const { return NumArgs; }
+
+ /// getArg - Return the specified argument.
+ Expr *getArg(unsigned Arg) {
+ assert(Arg < NumArgs && "Arg access out of range!");
+ return Args[Arg];
+ }
+ const Expr *getArg(unsigned Arg) const {
+ assert(Arg < NumArgs && "Arg access out of range!");
+ return Args[Arg];
+ }
+
+ /// getNumCommas - Return the number of commas that must have been present in
+ /// this function call.
+ unsigned getNumCommas() const { return NumArgs ? NumArgs - 1 : 0; }
+
+ SourceRange getSourceRange() const {
+ return SourceRange(Fn->getLocStart(), RParenLoc);
+ }
+
+ virtual void visit(StmtVisitor &Visitor);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CallExprClass;
+ }
+ static bool classof(const CallExpr *) { return true; }
+};
+
+/// MemberExpr - [C99 6.5.2.3] Structure and Union Members.
+///
+class MemberExpr : public Expr {
+ Expr *Base;
+ FieldDecl *MemberDecl;
+ SourceLocation MemberLoc;
+ bool IsArrow; // True if this is "X->F", false if this is "X.F".
+public:
+ MemberExpr(Expr *base, bool isarrow, FieldDecl *memberdecl, SourceLocation l)
+ : Expr(MemberExprClass, memberdecl->getType()),
+ Base(base), MemberDecl(memberdecl), MemberLoc(l), IsArrow(isarrow) {}
+
+ Expr *getBase() const { return Base; }
+ FieldDecl *getMemberDecl() const { return MemberDecl; }
+ bool isArrow() const { return IsArrow; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(getBase()->getLocStart(), MemberLoc);
+ }
+ virtual SourceLocation getExprLoc() const { return MemberLoc; }
+
+ virtual void visit(StmtVisitor &Visitor);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == MemberExprClass;
+ }
+ static bool classof(const MemberExpr *) { return true; }
+};
+
+/// CastExpr - [C99 6.5.4] Cast Operators.
+///
+class CastExpr : public Expr {
+ QualType Ty;
+ Expr *Op;
+ SourceLocation Loc; // the location of the left paren
+public:
+ CastExpr(QualType ty, Expr *op, SourceLocation l) :
+ Expr(CastExprClass, ty), Ty(ty), Op(op), Loc(l) {}
+ CastExpr(StmtClass SC, QualType ty, Expr *op) :
+ Expr(SC, QualType()), Ty(ty), Op(op), Loc(SourceLocation()) {}
+
+ SourceLocation getLParenLoc() const { return Loc; }
+
+ QualType getDestType() const { return Ty; }
+ Expr *getSubExpr() const { return Op; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(Loc, getSubExpr()->getSourceRange().End());
+ }
+ virtual void visit(StmtVisitor &Visitor);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CastExprClass;
+ }
+ static bool classof(const CastExpr *) { return true; }
+};
+
+
+class BinaryOperator : public Expr {
+public:
+ enum Opcode {
+ // Operators listed in order of precedence.
+ Mul, Div, Rem, // [C99 6.5.5] Multiplicative operators.
+ Add, Sub, // [C99 6.5.6] Additive operators.
+ Shl, Shr, // [C99 6.5.7] Bitwise shift operators.
+ LT, GT, LE, GE, // [C99 6.5.8] Relational operators.
+ EQ, NE, // [C99 6.5.9] Equality operators.
+ And, // [C99 6.5.10] Bitwise AND operator.
+ Xor, // [C99 6.5.11] Bitwise XOR operator.
+ Or, // [C99 6.5.12] Bitwise OR operator.
+ LAnd, // [C99 6.5.13] Logical AND operator.
+ LOr, // [C99 6.5.14] Logical OR operator.
+ Assign, MulAssign,// [C99 6.5.16] Assignment operators.
+ DivAssign, RemAssign,
+ AddAssign, SubAssign,
+ ShlAssign, ShrAssign,
+ AndAssign, XorAssign,
+ OrAssign,
+ Comma // [C99 6.5.17] Comma operator.
+ };
+
+ BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy)
+ : Expr(BinaryOperatorClass, ResTy), LHS(lhs), RHS(rhs), Opc(opc) {
+ assert(!isCompoundAssignmentOp() &&
+ "Use ArithAssignBinaryOperator for compound assignments");
+ }
+
+ Opcode getOpcode() const { return Opc; }
+ Expr *getLHS() const { return LHS; }
+ Expr *getRHS() const { return RHS; }
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(getLHS()->getLocStart(), getRHS()->getLocEnd());
+ }
+
+ /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
+ /// corresponds to, e.g. "<<=".
+ static const char *getOpcodeStr(Opcode Op);
+
+ /// predicates to categorize the respective opcodes.
+ bool isMultiplicativeOp() const { return Opc >= Mul && Opc <= Rem; }
+ bool isAdditiveOp() const { return Opc == Add || Opc == Sub; }
+ bool isShiftOp() const { return Opc == Shl || Opc == Shr; }
+ bool isBitwiseOp() const { return Opc >= And && Opc <= Or; }
+ bool isRelationalOp() const { return Opc >= LT && Opc <= GE; }
+ bool isEqualityOp() const { return Opc == EQ || Opc == NE; }
+ bool isLogicalOp() const { return Opc == LAnd || Opc == LOr; }
+ bool isAssignmentOp() const { return Opc >= Assign && Opc <= OrAssign; }
+ bool isCompoundAssignmentOp() const { return Opc > Assign && Opc <= OrAssign;}
+ bool isShiftAssignOp() const { return Opc == ShlAssign || Opc == ShrAssign; }
+
+ virtual void visit(StmtVisitor &Visitor);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == BinaryOperatorClass;
+ }
+ static bool classof(const BinaryOperator *) { return true; }
+private:
+ Expr *LHS, *RHS;
+ Opcode Opc;
+protected:
+ BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, bool dead)
+ : Expr(BinaryOperatorClass, ResTy), LHS(lhs), RHS(rhs), Opc(opc) {
+ }
+};
+
+/// CompoundAssignOperator - For compound assignments (e.g. +=), we keep
+/// track of the type the operation is performed in. Due to the semantics of
+/// these operators, the operands are promoted, the aritmetic performed, an
+/// implicit conversion back to the result type done, then the assignment takes
+/// place. This captures the intermediate type which the computation is done
+/// in.
+class CompoundAssignOperator : public BinaryOperator {
+ QualType ComputationType;
+public:
+ CompoundAssignOperator(Expr *lhs, Expr *rhs, Opcode opc,
+ QualType ResType, QualType CompType)
+ : BinaryOperator(lhs, rhs, opc, ResType, true), ComputationType(CompType) {
+ assert(isCompoundAssignmentOp() &&
+ "Only should be used for compound assignments");
+ }
+
+ QualType getComputationType() const { return ComputationType; }
+
+ static bool classof(const CompoundAssignOperator *) { return true; }
+ static bool classof(const BinaryOperator *B) {
+ return B->isCompoundAssignmentOp();
+ }
+ static bool classof(const Stmt *S) {
+ return isa<BinaryOperator>(S) && classof(cast<BinaryOperator>(S));
+ }
+};
+
+/// ConditionalOperator - The ?: operator. Note that LHS may be null when the
+/// GNU "missing LHS" extension is in use.
+///
+class ConditionalOperator : public Expr {
+ Expr *Cond, *LHS, *RHS; // Left/Middle/Right hand sides.
+public:
+ ConditionalOperator(Expr *cond, Expr *lhs, Expr *rhs, QualType t)
+ : Expr(ConditionalOperatorClass, t), Cond(cond), LHS(lhs), RHS(rhs) {}
+
+ Expr *getCond() const { return Cond; }
+ Expr *getLHS() const { return LHS; }
+ Expr *getRHS() const { return RHS; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(getCond()->getLocStart(), getRHS()->getLocEnd());
+ }
+ virtual void visit(StmtVisitor &Visitor);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ConditionalOperatorClass;
+ }
+ static bool classof(const ConditionalOperator *) { return true; }
+};
+
+/// AddrLabel - The GNU address of label extension, representing &&label.
+class AddrLabel : public Expr {
+ SourceLocation AmpAmpLoc, LabelLoc;
+ LabelStmt *Label;
+public:
+ AddrLabel(SourceLocation AALoc, SourceLocation LLoc, LabelStmt *L, QualType t)
+ : Expr(AddrLabelClass, t), AmpAmpLoc(AALoc), LabelLoc(LLoc), Label(L) {}
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(AmpAmpLoc, LabelLoc);
+ }
+
+ LabelStmt *getLabel() const { return Label; }
+
+ virtual void visit(StmtVisitor &Visitor);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == AddrLabelClass;
+ }
+ static bool classof(const AddrLabel *) { return true; }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
new file mode 100644
index 0000000..cfffead
--- /dev/null
+++ b/include/clang/AST/ExprCXX.h
@@ -0,0 +1,81 @@
+//===--- ExprCXX.h - Classes for representing expressions -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Bill Wendling and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the Expr interface and subclasses for C++ expressions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_EXPRCXX_H
+#define LLVM_CLANG_AST_EXPRCXX_H
+
+#include "clang/AST/Expr.h"
+
+namespace clang {
+
+ //===--------------------------------------------------------------------===//
+ // C++ Expressions.
+ //===--------------------------------------------------------------------===//
+
+ /// CXXCastExpr - [C++ 5.2.7, 5.2.9, 5.2.10, 5.2.11] C++ Cast Operators.
+ ///
+ class CXXCastExpr : public Expr {
+ public:
+ enum Opcode {
+ DynamicCast,
+ StaticCast,
+ ReinterpretCast,
+ ConstCast
+ };
+ private:
+ QualType Ty;
+ Opcode Opc;
+ Expr *Op;
+ SourceLocation Loc; // the location of the casting op
+ public:
+ CXXCastExpr(Opcode op, QualType ty, Expr *expr, SourceLocation l)
+ : Expr(CXXCastExprClass, ty), Ty(ty), Opc(op), Op(expr), Loc(l) {}
+
+ QualType getDestType() const { return Ty; }
+ Expr *getSubExpr() const { return Op; }
+
+ Opcode getOpcode() const { return Opc; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(Loc, getSubExpr()->getSourceRange().End());
+ }
+ virtual void visit(StmtVisitor &Visitor);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXCastExprClass;
+ }
+ static bool classof(const CXXCastExpr *) { return true; }
+ };
+
+ /// CXXBoolLiteralExpr - [C++ 2.13.5] C++ Boolean Literal.
+ ///
+ class CXXBoolLiteralExpr : public Expr {
+ bool Value;
+ SourceLocation Loc;
+ public:
+ CXXBoolLiteralExpr(bool val, SourceLocation l) :
+ Expr(CXXBoolLiteralExprClass, QualType()), Value(val), Loc(l) {}
+
+ bool getValue() const { return Value; }
+
+ virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
+
+ virtual void visit(StmtVisitor &Visitor);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXBoolLiteralExprClass;
+ }
+ static bool classof(const CXXBoolLiteralExpr *) { return true; }
+ };
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
new file mode 100644
index 0000000..f3fb907
--- /dev/null
+++ b/include/clang/AST/Stmt.h
@@ -0,0 +1,378 @@
+//===--- Stmt.h - Classes for representing statements -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the Stmt interface and subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_STMT_H
+#define LLVM_CLANG_AST_STMT_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/SmallVector.h"
+#include <iosfwd>
+
+namespace clang {
+ class Expr;
+ class Decl;
+ class IdentifierInfo;
+ class StmtVisitor;
+
+/// Stmt - This represents one statement.
+///
+class Stmt {
+public:
+ enum StmtClass {
+#define STMT(N, CLASS, PARENT) CLASS##Class = N,
+#define FIRST_STMT(N) firstStmtConstant = N,
+#define LAST_STMT(N) lastStmtConstant = N,
+#define FIRST_EXPR(N) firstExprConstant = N,
+#define LAST_EXPR(N) lastExprConstant = N
+#include "clang/AST/StmtNodes.def"
+};
+private:
+ const StmtClass sClass;
+public:
+ Stmt(StmtClass SC) : sClass(SC) {
+ if (Stmt::CollectingStats()) Stmt::addStmtClass(SC);
+ }
+ virtual ~Stmt() {}
+
+ StmtClass getStmtClass() const { return sClass; }
+ const char *getStmtClassName() const;
+
+ // global temp stats (until we have a per-module visitor)
+ static void addStmtClass(const StmtClass s);
+ static bool CollectingStats(bool enable=false);
+ static void PrintStats();
+
+ void dump() const;
+ void print(std::ostream &OS) const;
+
+ // Implement visitor support.
+ virtual void visit(StmtVisitor &Visitor);
+
+ // Implement isa<T> support.
+ static bool classof(const Stmt *) { return true; }
+};
+
+/// DeclStmt - Adaptor class for mixing declarations with statements and
+/// expressions. For example, CompoundStmt mixes statements, expressions
+/// and declarations (variables, types). Another example is ForStmt, where
+/// the first statement can be an expression or a declaration.
+///
+class DeclStmt : public Stmt {
+ Decl *TheDecl;
+public:
+ DeclStmt(Decl *D) : Stmt(DeclStmtClass), TheDecl(D) {}
+
+ const Decl *getDecl() const { return TheDecl; }
+ Decl *getDecl() { return TheDecl; }
+
+ virtual void visit(StmtVisitor &Visitor);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == DeclStmtClass;
+ }
+ static bool classof(const DeclStmt *) { return true; }
+};
+
+/// NullStmt - This is the null statement ";": C99 6.8.3p3.
+///
+class NullStmt : public Stmt {
+ SourceLocation SemiLoc;
+public:
+ NullStmt(SourceLocation L) : Stmt(NullStmtClass), SemiLoc(L) {}
+
+ SourceLocation getSemiLoc() const { return SemiLoc; }
+
+ virtual void visit(StmtVisitor &Visitor);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == NullStmtClass;
+ }
+ static bool classof(const NullStmt *) { return true; }
+};
+
+/// CompoundStmt - This represents a group of statements like { stmt stmt }.
+///
+class CompoundStmt : public Stmt {
+ llvm::SmallVector<Stmt*, 16> Body;
+public:
+ CompoundStmt(Stmt **StmtStart, unsigned NumStmts)
+ : Stmt(CompoundStmtClass), Body(StmtStart, StmtStart+NumStmts) {}
+
+ typedef llvm::SmallVector<Stmt*, 16>::iterator body_iterator;
+ body_iterator body_begin() { return Body.begin(); }
+ body_iterator body_end() { return Body.end(); }
+
+ typedef llvm::SmallVector<Stmt*, 16>::const_iterator const_body_iterator;
+ const_body_iterator body_begin() const { return Body.begin(); }
+ const_body_iterator body_end() const { return Body.end(); }
+
+ void push_back(Stmt *S) { Body.push_back(S); }
+
+ virtual void visit(StmtVisitor &Visitor);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CompoundStmtClass;
+ }
+ static bool classof(const CompoundStmt *) { return true; }
+};
+
+class CaseStmt : public Stmt {
+ Expr *LHSVal;
+ Expr *RHSVal; // Non-null for GNU "case 1 ... 4" extension
+ Stmt *SubStmt;
+public:
+ CaseStmt(Expr *lhs, Expr *rhs, Stmt *substmt)
+ : Stmt(CaseStmtClass), LHSVal(lhs), RHSVal(rhs), SubStmt(substmt) {}
+
+ Expr *getLHS() { return LHSVal; }
+ Expr *getRHS() { return RHSVal; }
+ Stmt *getSubStmt() { return SubStmt; }
+
+ virtual void visit(StmtVisitor &Visitor);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CaseStmtClass;
+ }
+ static bool classof(const CaseStmt *) { return true; }
+};
+
+class DefaultStmt : public Stmt {
+ Stmt *SubStmt;
+public:
+ DefaultStmt(Stmt *substmt) : Stmt(DefaultStmtClass), SubStmt(substmt) {}
+
+ Stmt *getSubStmt() { return SubStmt; }
+
+ virtual void visit(StmtVisitor &Visitor);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == DefaultStmtClass;
+ }
+ static bool classof(const DefaultStmt *) { return true; }
+};
+
+class LabelStmt : public Stmt {
+ SourceLocation IdentLoc;
+ IdentifierInfo *Label;
+ Stmt *SubStmt;
+public:
+ LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt)
+ : Stmt(LabelStmtClass), IdentLoc(IL), Label(label), SubStmt(substmt) {}
+
+ SourceLocation getIdentLoc() const { return IdentLoc; }
+ IdentifierInfo *getID() const { return Label; }
+ const char *getName() const;
+ Stmt *getSubStmt() { return SubStmt; }
+ const Stmt *getSubStmt() const { return SubStmt; }
+
+ void setIdentLoc(SourceLocation L) { IdentLoc = L; }
+ void setSubStmt(Stmt *SS) { SubStmt = SS; }
+
+ virtual void visit(StmtVisitor &Visitor);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == LabelStmtClass;
+ }
+ static bool classof(const LabelStmt *) { return true; }
+};
+
+
+/// IfStmt - This represents an if/then/else.
+///
+class IfStmt : public Stmt {
+ Expr *Cond;
+ Stmt *Then, *Else;
+public:
+ IfStmt(Expr *cond, Stmt *then, Stmt *elsev = 0)
+ : Stmt(IfStmtClass), Cond(cond), Then(then), Else(elsev) {}
+
+ const Expr *getCond() const { return Cond; }
+ const Stmt *getThen() const { return Then; }
+ const Stmt *getElse() const { return Else; }
+
+ Expr *getCond() { return Cond; }
+ Stmt *getThen() { return Then; }
+ Stmt *getElse() { return Else; }
+
+ virtual void visit(StmtVisitor &Visitor);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == IfStmtClass;
+ }
+ static bool classof(const IfStmt *) { return true; }
+};
+
+/// SwitchStmt - This represents a 'switch' stmt.
+///
+class SwitchStmt : public Stmt {
+ Expr *Cond;
+ Stmt *Body;
+public:
+ SwitchStmt(Expr *cond, Stmt *body)
+ : Stmt(SwitchStmtClass), Cond(cond), Body(body) {}
+
+ Expr *getCond() { return Cond; }
+ Stmt *getBody() { return Body; }
+
+ virtual void visit(StmtVisitor &Visitor);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == SwitchStmtClass;
+ }
+ static bool classof(const SwitchStmt *) { return true; }
+};
+
+
+/// WhileStmt - This represents a 'while' stmt.
+///
+class WhileStmt : public Stmt {
+ Expr *Cond;
+ Stmt *Body;
+public:
+ WhileStmt(Expr *cond, Stmt *body)
+ : Stmt(WhileStmtClass), Cond(cond), Body(body) {}
+
+ Expr *getCond() { return Cond; }
+ const Expr *getCond() const { return Cond; }
+ Stmt *getBody() { return Body; }
+ const Stmt *getBody() const { return Body; }
+
+ virtual void visit(StmtVisitor &Visitor);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == WhileStmtClass;
+ }
+ static bool classof(const WhileStmt *) { return true; }
+};
+
+/// DoStmt - This represents a 'do/while' stmt.
+///
+class DoStmt : public Stmt {
+ Stmt *Body;
+ Expr *Cond;
+public:
+ DoStmt(Stmt *body, Expr *cond)
+ : Stmt(DoStmtClass), Body(body), Cond(cond) {}
+
+ Stmt *getBody() { return Body; }
+ const Stmt *getBody() const { return Body; }
+ Expr *getCond() { return Cond; }
+ const Expr *getCond() const { return Cond; }
+
+ virtual void visit(StmtVisitor &Visitor);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == DoStmtClass;
+ }
+ static bool classof(const DoStmt *) { return true; }
+};
+
+
+/// ForStmt - This represents a 'for (init;cond;inc)' stmt. Note that any of
+/// the init/cond/inc parts of the ForStmt will be null if they were not
+/// specified in the source.
+///
+class ForStmt : public Stmt {
+ Stmt *Init; // Expression or declstmt.
+ Expr *Cond, *Inc;
+ Stmt *Body;
+public:
+ ForStmt(Stmt *init, Expr *cond, Expr *inc, Stmt *body)
+ : Stmt(ForStmtClass), Init(init), Cond(cond), Inc(inc), Body(body) {}
+
+ Stmt *getInit() { return Init; }
+ Expr *getCond() { return Cond; }
+ Expr *getInc() { return Inc; }
+ Stmt *getBody() { return Body; }
+
+ const Stmt *getInit() const { return Init; }
+ const Expr *getCond() const { return Cond; }
+ const Expr *getInc() const { return Inc; }
+ const Stmt *getBody() const { return Body; }
+
+ virtual void visit(StmtVisitor &Visitor);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ForStmtClass;
+ }
+ static bool classof(const ForStmt *) { return true; }
+};
+
+/// GotoStmt - This represents a direct goto.
+///
+class GotoStmt : public Stmt {
+ LabelStmt *Label;
+public:
+ GotoStmt(LabelStmt *label) : Stmt(GotoStmtClass), Label(label) {}
+
+ LabelStmt *getLabel() const { return Label; }
+
+ virtual void visit(StmtVisitor &Visitor);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == GotoStmtClass;
+ }
+ static bool classof(const GotoStmt *) { return true; }
+};
+
+/// IndirectGotoStmt - This represents an indirect goto.
+///
+class IndirectGotoStmt : public Stmt {
+ Expr *Target;
+public:
+ IndirectGotoStmt(Expr *target) : Stmt(IndirectGotoStmtClass),
+ Target(target) {}
+
+ Expr *getTarget() { return Target; }
+
+ virtual void visit(StmtVisitor &Visitor);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == IndirectGotoStmtClass;
+ }
+ static bool classof(const IndirectGotoStmt *) { return true; }
+};
+
+
+/// ContinueStmt - This represents a continue.
+///
+class ContinueStmt : public Stmt {
+public:
+ ContinueStmt() : Stmt(ContinueStmtClass) {}
+ virtual void visit(StmtVisitor &Visitor);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ContinueStmtClass;
+ }
+ static bool classof(const ContinueStmt *) { return true; }
+};
+
+/// BreakStmt - This represents a break.
+///
+class BreakStmt : public Stmt {
+public:
+ BreakStmt() : Stmt(BreakStmtClass) {}
+ virtual void visit(StmtVisitor &Visitor);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == BreakStmtClass;
+ }
+ static bool classof(const BreakStmt *) { return true; }
+};
+
+
+/// ReturnStmt - This represents a return, optionally of an expression.
+///
+class ReturnStmt : public Stmt {
+ Expr *RetExpr;
+public:
+ ReturnStmt(Expr *E = 0) : Stmt(ReturnStmtClass), RetExpr(E) {}
+
+ const Expr *getRetValue() const { return RetExpr; }
+ Expr *getRetValue() { return RetExpr; }
+
+ virtual void visit(StmtVisitor &Visitor);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == ReturnStmtClass;
+ }
+ static bool classof(const ReturnStmt *) { return true; }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/AST/StmtNodes.def b/include/clang/AST/StmtNodes.def
new file mode 100644
index 0000000..6595223
--- /dev/null
+++ b/include/clang/AST/StmtNodes.def
@@ -0,0 +1,74 @@
+//===-- StmtNodes.def - Metadata about Stmt AST nodes -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the AST Node info database.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef FIRST_STMT
+#define FIRST_STMT(n)
+#define LAST_STMT(n)
+#endif
+
+#ifndef FIRST_EXPR
+#define FIRST_EXPR(n)
+#define LAST_EXPR(n)
+#endif
+
+// Normal Statements.
+FIRST_STMT(1)
+STMT( 1, NullStmt , Stmt)
+STMT( 2, CompoundStmt , Stmt)
+STMT( 3, CaseStmt , Stmt)
+STMT( 4, DefaultStmt , Stmt)
+STMT( 5, LabelStmt , Stmt)
+STMT( 6, IfStmt , Stmt)
+STMT( 7, SwitchStmt , Stmt)
+STMT( 8, WhileStmt , Stmt)
+STMT( 9, DoStmt , Stmt)
+STMT(10, ForStmt , Stmt)
+STMT(11, GotoStmt , Stmt)
+STMT(12, IndirectGotoStmt, Stmt)
+STMT(13, ContinueStmt , Stmt)
+STMT(14, BreakStmt , Stmt)
+STMT(15, ReturnStmt , Stmt)
+STMT(16, DeclStmt , Stmt)
+LAST_STMT(16)
+
+FIRST_EXPR(32)
+// Expressions.
+STMT(32, Expr , Stmt)
+STMT(33, DeclRefExpr , Expr)
+STMT(34, IntegerLiteral , Expr)
+STMT(35, FloatingLiteral , Expr)
+STMT(36, StringLiteral , Expr)
+STMT(37, CharacterLiteral , Expr)
+STMT(38, ParenExpr , Expr)
+STMT(39, UnaryOperator , Expr)
+STMT(40, SizeOfAlignOfTypeExpr, Expr)
+STMT(41, ArraySubscriptExpr , Expr)
+STMT(42, CallExpr , Expr)
+STMT(43, MemberExpr , Expr)
+STMT(44, CastExpr , Expr)
+STMT(45, BinaryOperator , Expr)
+STMT(46, ConditionalOperator , Expr)
+
+// GNU Extensions.
+STMT(47, AddrLabel , Expr)
+
+// C++ Expressions.
+STMT(48, CXXCastExpr , Expr)
+STMT(49, CXXBoolLiteralExpr , Expr)
+LAST_EXPR(49)
+
+#undef STMT
+#undef FIRST_STMT
+#undef LAST_STMT
+#undef FIRST_EXPR
+#undef LAST_EXPR
diff --git a/include/clang/AST/StmtVisitor.h b/include/clang/AST/StmtVisitor.h
new file mode 100644
index 0000000..9422765
--- /dev/null
+++ b/include/clang/AST/StmtVisitor.h
@@ -0,0 +1,40 @@
+//===--- StmtVisitor.h - Visitor for Stmt subclasses ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the StmtVisitor interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_STMTVISITOR_H
+#define LLVM_CLANG_AST_STMTVISITOR_H
+
+namespace clang {
+ class Stmt;
+ // Add prototypes for all AST node classes.
+#define STMT(N, CLASS, PARENT) \
+ class CLASS;
+#include "clang/AST/StmtNodes.def"
+
+/// StmtVisitor - This class implements a simple visitor for Stmt subclasses.
+/// Since Expr derives from Stmt, this also includes support for visiting Exprs.
+class StmtVisitor {
+public:
+ virtual ~StmtVisitor();
+
+ virtual void VisitStmt(Stmt *Node) {}
+
+ // Implement all the methods with the StmtNodes.def file.
+#define STMT(N, CLASS, PARENT) \
+ virtual void Visit##CLASS(CLASS *Node);
+#include "clang/AST/StmtNodes.def"
+};
+
+}
+
+#endif
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
new file mode 100644
index 0000000..93969b2
--- /dev/null
+++ b/include/clang/AST/Type.h
@@ -0,0 +1,648 @@
+//===--- Type.h - C Language Family Type Representation ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the Type interface and subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_TYPE_H
+#define LLVM_CLANG_AST_TYPE_H
+
+#include "llvm/Support/Casting.h"
+#include "llvm/ADT/FoldingSet.h"
+
+using llvm::isa;
+using llvm::cast;
+using llvm::cast_or_null;
+using llvm::dyn_cast;
+using llvm::dyn_cast_or_null;
+
+namespace clang {
+ class ASTContext;
+ class Type;
+ class TypedefDecl;
+ class TagDecl;
+ class RecordDecl;
+ class EnumDecl;
+ class Expr;
+ class SourceLocation;
+
+/// QualType - For efficiency, we don't store CVR-qualified types as nodes on
+/// their own: instead each reference to a type stores the qualifiers. This
+/// greatly reduces the number of nodes we need to allocate for types (for
+/// example we only need one for 'int', 'const int', 'volatile int',
+/// 'const volatile int', etc).
+///
+/// As an added efficiency bonus, instead of making this a pair, we just store
+/// the three bits we care about in the low bits of the pointer. To handle the
+/// packing/unpacking, we make QualType be a simple wrapper class that acts like
+/// a smart pointer.
+class QualType {
+ uintptr_t ThePtr;
+public:
+ enum TQ { // NOTE: These flags must be kept in sync with DeclSpec::TQ.
+ Const = 0x1,
+ Restrict = 0x2,
+ Volatile = 0x4,
+ CVRFlags = Const|Restrict|Volatile
+ };
+
+ QualType() : ThePtr(0) {}
+
+ QualType(Type *Ptr, unsigned Quals) {
+ assert((Quals & ~CVRFlags) == 0 && "Invalid type qualifiers!");
+ ThePtr = reinterpret_cast<uintptr_t>(Ptr);
+ assert((ThePtr & CVRFlags) == 0 && "Type pointer not 8-byte aligned?");
+ ThePtr |= Quals;
+ }
+
+ static QualType getFromOpaquePtr(void *Ptr) {
+ QualType T;
+ T.ThePtr = reinterpret_cast<uintptr_t>(Ptr);
+ return T;
+ }
+
+ unsigned getQualifiers() const {
+ return ThePtr & CVRFlags;
+ }
+ Type *getTypePtr() const {
+ return reinterpret_cast<Type*>(ThePtr & ~CVRFlags);
+ }
+
+ void *getAsOpaquePtr() const {
+ return reinterpret_cast<void*>(ThePtr);
+ }
+
+ Type &operator*() const {
+ return *getTypePtr();
+ }
+
+ Type *operator->() const {
+ return getTypePtr();
+ }
+
+ /// isNull - Return true if this QualType doesn't point to a type yet.
+ bool isNull() const {
+ return ThePtr == 0;
+ }
+
+ bool isConstQualified() const {
+ return ThePtr & Const;
+ }
+ bool isVolatileQualified() const {
+ return ThePtr & Volatile;
+ }
+ bool isRestrictQualified() const {
+ return ThePtr & Restrict;
+ }
+
+ QualType getQualifiedType(unsigned TQs) const {
+ return QualType(getTypePtr(), TQs);
+ }
+
+ QualType getUnqualifiedType() const {
+ return QualType(getTypePtr(), 0);
+ }
+
+ /// operator==/!= - Indicate whether the specified types and qualifiers are
+ /// identical.
+ bool operator==(const QualType &RHS) const {
+ return ThePtr == RHS.ThePtr;
+ }
+ bool operator!=(const QualType &RHS) const {
+ return ThePtr != RHS.ThePtr;
+ }
+ std::string getAsString() const {
+ std::string S;
+ getAsStringInternal(S);
+ return S;
+ }
+ void getAsStringInternal(std::string &Str) const;
+
+ void dump(const char *s = 0) const;
+
+ /// getCanonicalType - Return the canonical version of this type, with the
+ /// appropriate type qualifiers on it.
+ inline QualType getCanonicalType() const;
+
+private:
+};
+
+} // end clang.
+
+namespace llvm {
+/// Implement simplify_type for QualType, so that we can dyn_cast from QualType
+/// to a specific Type class.
+template<> struct simplify_type<const ::clang::QualType> {
+ typedef ::clang::Type* SimpleType;
+ static SimpleType getSimplifiedValue(const ::clang::QualType &Val) {
+ return Val.getTypePtr();
+ }
+};
+template<> struct simplify_type< ::clang::QualType>
+ : public simplify_type<const ::clang::QualType> {};
+}
+
+namespace clang {
+
+/// Type - This is the base class of the type hierarchy. A central concept
+/// with types is that each type always has a canonical type. A canonical type
+/// is the type with any typedef names stripped out of it or the types it
+/// references. For example, consider:
+///
+/// typedef int foo;
+/// typedef foo* bar;
+/// 'int *' 'foo *' 'bar'
+///
+/// There will be a Type object created for 'int'. Since int is canonical, its
+/// canonicaltype pointer points to itself. There is also a Type for 'foo' (a
+/// TypeNameType). Its CanonicalType pointer points to the 'int' Type. Next
+/// there is a PointerType that represents 'int*', which, like 'int', is
+/// canonical. Finally, there is a PointerType type for 'foo*' whose canonical
+/// type is 'int*', and there is a TypeNameType for 'bar', whose canonical type
+/// is also 'int*'.
+///
+/// Non-canonical types are useful for emitting diagnostics, without losing
+/// information about typedefs being used. Canonical types are useful for type
+/// comparisons (they allow by-pointer equality tests) and useful for reasoning
+/// about whether something has a particular form (e.g. is a function type),
+/// because they implicitly, recursively, strip all typedefs out of a type.
+///
+/// Types, once created, are immutable.
+///
+class Type {
+public:
+ enum TypeClass {
+ Builtin, Complex, Pointer, Reference, Array, Vector,
+ FunctionNoProto, FunctionProto,
+ TypeName, Tagged
+ };
+private:
+ QualType CanonicalType;
+
+ /// TypeClass bitfield - Enum that specifies what subclass this belongs to.
+ /// Note that this should stay at the end of the ivars for Type so that
+ /// subclasses can pack their bitfields into the same word.
+ TypeClass TC : 4;
+protected:
+ Type(TypeClass tc, QualType Canonical)
+ : CanonicalType(Canonical.isNull() ? QualType(this,0) : Canonical), TC(tc){}
+ virtual ~Type();
+ friend class ASTContext;
+public:
+ TypeClass getTypeClass() const { return TC; }
+
+ bool isCanonical() const { return CanonicalType.getTypePtr() == this; }
+
+ /// Types are partitioned into 3 broad categories (C99 6.2.5p1):
+ /// object types, function types, and incomplete types.
+
+ /// isObjectType - types that fully describe objects. An object is a region
+ /// of memory that can be examined and stored into (H&S).
+ bool isObjectType() const;
+
+ /// isFunctionType - types that describe functions.
+ bool isFunctionType() const;
+
+ /// isIncompleteType - Return true if this is an incomplete type.
+ /// A type that can describe objects, but which lacks information needed to
+ /// determine its size (e.g. void, or a fwd declared struct). Clients of this
+ /// routine will need to determine if the size is actually required.
+ bool isIncompleteType() const;
+
+ /// Helper methods to distinguish type categories. All type predicates
+ /// operate on the canonical type, ignoring typedefs.
+ bool isIntegerType() const; // C99 6.2.5p17 (int, char, bool, enum)
+
+ /// Floating point categories.
+ bool isRealFloatingType() const; // C99 6.2.5p10 (float, double, long double)
+ bool isComplexType() const; // C99 6.2.5p11 (complex)
+ bool isFloatingType() const; // C99 6.2.5p11 (real floating + complex)
+ bool isRealType() const; // C99 6.2.5p17 (real floating + integer)
+ bool isArithmeticType() const; // C99 6.2.5p18 (integer + floating)
+
+ /// Vector types
+ bool isVectorType() const; // GCC vector type.
+
+ /// Derived types (C99 6.2.5p20). isFunctionType() is also a derived type.
+ bool isDerivedType() const;
+ bool isPointerType() const;
+ bool isReferenceType() const;
+ bool isArrayType() const;
+ bool isStructureType() const;
+ bool isUnionType() const;
+
+ bool isVoidType() const; // C99 6.2.5p19
+ bool isScalarType() const; // C99 6.2.5p21 (arithmetic + pointers)
+ bool isAggregateType() const; // C99 6.2.5p21 (arrays, structures)
+
+ /// More type predicates useful for type checking/promotion
+ bool isPromotableIntegerType() const; // C99 6.3.1.1p2
+
+ /// isSignedIntegerType - Return true if this is an integer type that is
+ /// signed, according to C99 6.2.5p4.
+ bool isSignedIntegerType() const;
+
+ /// isUnsignedIntegerType - Return true if this is an integer type that is
+ /// unsigned, according to C99 6.2.5p6. Note that this returns true for _Bool.
+ bool isUnsignedIntegerType() const;
+
+ /// isConstantSizeType - Return true if this is not a variable sized type,
+ /// according to the rules of C99 6.7.5p3. If Loc is non-null, it is set to
+ /// the location of the subexpression that makes it a vla type. It is not
+ /// legal to call this on incomplete types.
+ bool isConstantSizeType(SourceLocation *Loc = 0) const;
+
+ /// Compatibility predicates used to check assignment expressions.
+ static bool typesAreCompatible(QualType, QualType); // C99 6.2.7p1
+ static bool tagTypesAreCompatible(QualType, QualType); // C99 6.2.7p1
+ static bool pointerTypesAreCompatible(QualType, QualType); // C99 6.7.5.1p2
+ static bool referenceTypesAreCompatible(QualType, QualType); // C++ 5.17p6
+ static bool functionTypesAreCompatible(QualType, QualType); // C99 6.7.5.3p15
+ static bool arrayTypesAreCompatible(QualType, QualType); // C99 6.7.5.2p6
+private:
+ QualType getCanonicalTypeInternal() const { return CanonicalType; }
+ friend class QualType;
+public:
+ virtual void getAsStringInternal(std::string &InnerString) const = 0;
+
+ static bool classof(const Type *) { return true; }
+};
+
+/// BuiltinType - This class is used for builtin types like 'int'. Builtin
+/// types are always canonical and have a literal name field.
+class BuiltinType : public Type {
+public:
+ enum Kind {
+ Void,
+
+ Bool, // This is bool and/or _Bool.
+ Char_U, // This is 'char' for targets where char is unsigned.
+ UChar, // This is explicitly qualified unsigned char.
+ UShort,
+ UInt,
+ ULong,
+ ULongLong,
+
+ Char_S, // This is 'char' for targets where char is signed.
+ SChar, // This is explicitly qualified signed char.
+ Short,
+ Int,
+ Long,
+ LongLong,
+
+ Float, Double, LongDouble
+ };
+private:
+ Kind TypeKind;
+public:
+ BuiltinType(Kind K) : Type(Builtin, QualType()), TypeKind(K) {}
+
+ Kind getKind() const { return TypeKind; }
+ const char *getName() const;
+
+ // the number of bits to represent the builtin type.
+ unsigned getSize() const;
+
+ virtual void getAsStringInternal(std::string &InnerString) const;
+
+ static bool classof(const Type *T) { return T->getTypeClass() == Builtin; }
+ static bool classof(const BuiltinType *) { return true; }
+};
+
+/// ComplexType - C99 6.2.5p11 - Complex values. This supports the C99 complex
+/// types (_Complex float etc) as well as the GCC integer complex extensions.
+///
+class ComplexType : public Type, public llvm::FoldingSetNode {
+ QualType ElementType;
+ ComplexType(QualType Element, QualType CanonicalPtr) :
+ Type(Complex, CanonicalPtr), ElementType(Element) {
+ }
+ friend class ASTContext; // ASTContext creates these.
+public:
+ QualType getElementType() const { return ElementType; }
+
+ virtual void getAsStringInternal(std::string &InnerString) const;
+
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, getElementType());
+ }
+ static void Profile(llvm::FoldingSetNodeID &ID, QualType Element) {
+ ID.AddPointer(Element.getAsOpaquePtr());
+ }
+
+ static bool classof(const Type *T) { return T->getTypeClass() == Complex; }
+ static bool classof(const ComplexType *) { return true; }
+};
+
+
+/// PointerType - C99 6.7.5.1 - Pointer Declarators.
+///
+class PointerType : public Type, public llvm::FoldingSetNode {
+ QualType PointeeType;
+ PointerType(QualType Pointee, QualType CanonicalPtr) :
+ Type(Pointer, CanonicalPtr), PointeeType(Pointee) {
+ }
+ friend class ASTContext; // ASTContext creates these.
+public:
+
+ QualType getPointeeType() const { return PointeeType; }
+
+ virtual void getAsStringInternal(std::string &InnerString) const;
+
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, getPointeeType());
+ }
+ static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) {
+ ID.AddPointer(Pointee.getAsOpaquePtr());
+ }
+
+ static bool classof(const Type *T) { return T->getTypeClass() == Pointer; }
+ static bool classof(const PointerType *) { return true; }
+};
+
+/// ReferenceType - C++ 8.3.2 - Reference Declarators.
+///
+class ReferenceType : public Type, public llvm::FoldingSetNode {
+ QualType ReferenceeType;
+ ReferenceType(QualType Referencee, QualType CanonicalRef) :
+ Type(Reference, CanonicalRef), ReferenceeType(Referencee) {
+ }
+ friend class ASTContext; // ASTContext creates these.
+public:
+ virtual void getAsStringInternal(std::string &InnerString) const;
+
+ QualType getReferenceeType() const { return ReferenceeType; }
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, getReferenceeType());
+ }
+ static void Profile(llvm::FoldingSetNodeID &ID, QualType Referencee) {
+ ID.AddPointer(Referencee.getAsOpaquePtr());
+ }
+
+ static bool classof(const Type *T) { return T->getTypeClass() == Reference; }
+ static bool classof(const ReferenceType *) { return true; }
+};
+
+/// ArrayType - C99 6.7.5.2 - Array Declarators.
+///
+class ArrayType : public Type, public llvm::FoldingSetNode {
+public:
+ /// ArraySizeModifier - Capture whether this is a normal array (e.g. int X[4])
+ /// an array with a static size (e.g. int X[static 4]), or with a star size
+ /// (e.g. int X[*]).
+ enum ArraySizeModifier {
+ Normal, Static, Star
+ };
+private:
+ /// NOTE: These fields are packed into the bitfields space in the Type class.
+ ArraySizeModifier SizeModifier : 2;
+
+ /// IndexTypeQuals - Capture qualifiers in declarations like:
+ /// 'int X[static restrict 4]'.
+ unsigned IndexTypeQuals : 3;
+
+ /// ElementType - The element type of the array.
+ QualType ElementType;
+
+ /// SizeExpr - The size is either a constant or assignment expression (for
+ /// Variable Length Arrays). VLA's are only permitted within a function block.
+ Expr *SizeExpr;
+
+ ArrayType(QualType et, ArraySizeModifier sm, unsigned tq, QualType can,
+ Expr *e)
+ : Type(Array, can), SizeModifier(sm), IndexTypeQuals(tq), ElementType(et),
+ SizeExpr(e) {}
+ friend class ASTContext; // ASTContext creates these.
+public:
+
+ QualType getElementType() const { return ElementType; }
+ ArraySizeModifier getSizeModifier() const { return SizeModifier; }
+ unsigned getIndexTypeQualifier() const { return IndexTypeQuals; }
+ Expr *getSize() const { return SizeExpr; }
+
+ virtual void getAsStringInternal(std::string &InnerString) const;
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, getSizeModifier(), getIndexTypeQualifier(), getElementType(),
+ getSize());
+ }
+ static void Profile(llvm::FoldingSetNodeID &ID,
+ ArraySizeModifier SizeModifier,
+ unsigned IndexTypeQuals, QualType ElementType,
+ Expr *SizeExpr) {
+ ID.AddInteger(SizeModifier);
+ ID.AddInteger(IndexTypeQuals);
+ ID.AddPointer(ElementType.getAsOpaquePtr());
+ ID.AddPointer(SizeExpr);
+ }
+
+ static bool classof(const Type *T) { return T->getTypeClass() == Array; }
+ static bool classof(const ArrayType *) { return true; }
+};
+
+/// VectorType -
+///
+class VectorType : public Type, public llvm::FoldingSetNode {
+ /// ElementType - The element type of the vector.
+ QualType ElementType;
+
+ /// NumElements - The number of elements in the vector.
+ unsigned NumElements;
+
+ VectorType(QualType vecType, unsigned vectorSize, QualType canonType) :
+ Type(Vector, canonType), ElementType(vecType), NumElements(vectorSize) {}
+ friend class ASTContext; // ASTContext creates these.
+public:
+
+ QualType getElementType() const { return ElementType; }
+ unsigned getNumElements() const { return NumElements; }
+
+ virtual void getAsStringInternal(std::string &InnerString) const;
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, getElementType(), getNumElements());
+ }
+ static void Profile(llvm::FoldingSetNodeID &ID,
+ QualType ElementType, unsigned NumElements) {
+ ID.AddPointer(ElementType.getAsOpaquePtr());
+ ID.AddInteger(NumElements);
+ }
+ static bool classof(const Type *T) { return T->getTypeClass() == Vector; }
+ static bool classof(const VectorType *) { return true; }
+};
+
+/// FunctionType - C99 6.7.5.3 - Function Declarators. This is the common base
+/// class of FunctionTypeNoProto and FunctionTypeProto.
+///
+class FunctionType : public Type {
+ /// SubClassData - This field is owned by the subclass, put here to pack
+ /// tightly with the ivars in Type.
+ bool SubClassData : 1;
+
+ // The type returned by the function.
+ QualType ResultType;
+protected:
+ FunctionType(TypeClass tc, QualType res, bool SubclassInfo,QualType Canonical)
+ : Type(tc, Canonical), SubClassData(SubclassInfo), ResultType(res) {}
+ bool getSubClassData() const { return SubClassData; }
+public:
+
+ QualType getResultType() const { return ResultType; }
+
+
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == FunctionNoProto ||
+ T->getTypeClass() == FunctionProto;
+ }
+ static bool classof(const FunctionType *) { return true; }
+};
+
+/// FunctionTypeNoProto - Represents a K&R-style 'int foo()' function, which has
+/// no information available about its arguments.
+class FunctionTypeNoProto : public FunctionType, public llvm::FoldingSetNode {
+ FunctionTypeNoProto(QualType Result, QualType Canonical)
+ : FunctionType(FunctionNoProto, Result, false, Canonical) {}
+ friend class ASTContext; // ASTContext creates these.
+public:
+ // No additional state past what FunctionType provides.
+
+ virtual void getAsStringInternal(std::string &InnerString) const;
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, getResultType());
+ }
+ static void Profile(llvm::FoldingSetNodeID &ID, QualType ResultType) {
+ ID.AddPointer(ResultType.getAsOpaquePtr());
+ }
+
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == FunctionNoProto;
+ }
+ static bool classof(const FunctionTypeNoProto *) { return true; }
+};
+
+/// FunctionTypeProto - Represents a prototype with argument type info, e.g.
+/// 'int foo(int)' or 'int foo(void)'. 'void' is represented as having no
+/// arguments, not as having a single void argument.
+class FunctionTypeProto : public FunctionType, public llvm::FoldingSetNode {
+ FunctionTypeProto(QualType Result, QualType *ArgArray, unsigned numArgs,
+ bool isVariadic, QualType Canonical)
+ : FunctionType(FunctionProto, Result, isVariadic, Canonical),
+ NumArgs(numArgs) {
+ for (unsigned i = 0; i != numArgs; ++i)
+ ArgInfo[i] = ArgArray[i];
+ }
+
+ /// NumArgs - The number of arguments this function has, not counting '...'.
+ unsigned NumArgs;
+
+ /// ArgInfo - This array holds the argument types. Note that this is actually
+ /// a variable-sized array, so it must be the last instance variable in the
+ /// class.
+ QualType ArgInfo[1];
+ friend class ASTContext; // ASTContext creates these.
+public:
+ unsigned getNumArgs() const { return NumArgs; }
+ QualType getArgType(unsigned i) const {
+ assert(i < NumArgs && "Invalid argument number!");
+ return ArgInfo[i];
+ }
+
+ bool isVariadic() const { return getSubClassData(); }
+
+ typedef const QualType *arg_type_iterator;
+ arg_type_iterator arg_type_begin() const { return ArgInfo; }
+ arg_type_iterator arg_type_end() const { return ArgInfo+NumArgs; }
+
+ virtual void getAsStringInternal(std::string &InnerString) const;
+
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == FunctionProto;
+ }
+ static bool classof(const FunctionTypeProto *) { return true; }
+
+ void Profile(llvm::FoldingSetNodeID &ID);
+ static void Profile(llvm::FoldingSetNodeID &ID, QualType Result,
+ QualType* ArgTys, unsigned NumArgs, bool isVariadic);
+};
+
+
+class TypedefType : public Type {
+ TypedefDecl *Decl;
+ TypedefType(TypedefDecl *D, QualType can) : Type(TypeName, can), Decl(D) {
+ assert(!isa<TypedefType>(can) && "Invalid canonical type");
+ }
+ friend class ASTContext; // ASTContext creates these.
+public:
+
+ TypedefDecl *getDecl() const { return Decl; }
+
+ virtual void getAsStringInternal(std::string &InnerString) const;
+
+ static bool classof(const Type *T) { return T->getTypeClass() == TypeName; }
+ static bool classof(const TypedefType *) { return true; }
+};
+
+
+class TagType : public Type {
+ TagDecl *Decl;
+ TagType(TagDecl *D, QualType can) : Type(Tagged, can), Decl(D) {}
+ friend class ASTContext; // ASTContext creates these.
+public:
+
+ TagDecl *getDecl() const { return Decl; }
+
+ virtual void getAsStringInternal(std::string &InnerString) const;
+
+ static bool classof(const Type *T) { return T->getTypeClass() == Tagged; }
+ static bool classof(const TagType *) { return true; }
+};
+
+/// RecordType - This is a helper class that allows the use of isa/cast/dyncast
+/// to detect TagType objects of structs/unions/classes.
+class RecordType : public TagType {
+ RecordType(); // DO NOT IMPLEMENT
+public:
+
+ RecordDecl *getDecl() const {
+ return reinterpret_cast<RecordDecl*>(TagType::getDecl());
+ }
+ // FIXME: This predicate is a helper to QualType/Type. It needs to
+ // recursively check all fields for const-ness. If any field is declared
+ // const, it needs to return false.
+ bool hasConstFields() const { return false; }
+
+ static bool classof(const Type *T);
+ static bool classof(const RecordType *) { return true; }
+};
+
+
+/// ...
+
+// TODO: When we support C++, we should have types for uses of template with
+// default parameters. We should be able to distinguish source use of
+// 'std::vector<int>' from 'std::vector<int, std::allocator<int> >'. Though they
+// specify the same type, we want to print the default argument only if
+// specified in the source code.
+
+/// getCanonicalType - Return the canonical version of this type, with the
+/// appropriate type qualifiers on it.
+inline QualType QualType::getCanonicalType() const {
+ return QualType(getTypePtr()->getCanonicalTypeInternal().getTypePtr(),
+ getQualifiers() |
+ getTypePtr()->getCanonicalTypeInternal().getQualifiers());
+}
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
new file mode 100644
index 0000000..07d38f2
--- /dev/null
+++ b/include/clang/Basic/Diagnostic.h
@@ -0,0 +1,158 @@
+//===--- Diagnostic.h - C Language Family Diagnostic Handling ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the Diagnostic-related interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_DIAGNOSTIC_H
+#define LLVM_CLANG_DIAGNOSTIC_H
+
+#include <string>
+
+namespace clang {
+ class DiagnosticClient;
+ class SourceLocation;
+ class SourceRange;
+
+ // Import the diagnostic enums themselves.
+ namespace diag {
+ /// diag::kind - All of the diagnostics that can be emitted by the frontend.
+ enum kind {
+#define DIAG(ENUM,FLAGS,DESC) ENUM,
+#include "DiagnosticKinds.def"
+ NUM_DIAGNOSTICS
+ };
+
+ /// Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs
+ /// to either MAP_IGNORE (nothing), MAP_WARNING (emit a warning), MAP_ERROR
+ /// (emit as an error), or MAP_DEFAULT (handle the default way).
+ enum Mapping {
+ MAP_DEFAULT = 0, //< Do not map this diagnostic.
+ MAP_IGNORE = 1, //< Map this diagnostic to nothing, ignore it.
+ MAP_WARNING = 2, //< Map this diagnostic to a warning.
+ MAP_ERROR = 3 //< Map this diagnostic to an error.
+ };
+ }
+
+/// Diagnostic - This concrete class is used by the front-end to report
+/// problems and issues. It massages the diagnostics (e.g. handling things like
+/// "report warnings as errors" and passes them off to the DiagnosticClient for
+/// reporting to the user.
+class Diagnostic {
+ bool WarningsAsErrors; // Treat warnings like errors:
+ bool WarnOnExtensions; // Enables warnings for gcc extensions: -pedantic.
+ bool ErrorOnExtensions; // Error on extensions: -pedantic-errors.
+ DiagnosticClient &Client;
+
+ /// DiagMappings - Mapping information for diagnostics. Mapping info is
+ /// packed into two bits per diagnostic.
+ unsigned char DiagMappings[(diag::NUM_DIAGNOSTICS+3)/4];
+
+ /// ErrorOccurred - This is set to true when an error is emitted, and is
+ /// sticky.
+ bool ErrorOccurred;
+
+ unsigned NumDiagnostics; // Number of diagnostics reported
+ unsigned NumErrors; // Number of diagnostics that are errors
+public:
+ explicit Diagnostic(DiagnosticClient &client);
+
+ //===--------------------------------------------------------------------===//
+ // Diagnostic characterization methods, used by a client to customize how
+ //
+ const DiagnosticClient &getClient() const { return Client; };
+
+ /// setWarningsAsErrors - When set to true, any warnings reported are issued
+ /// as errors.
+ void setWarningsAsErrors(bool Val) { WarningsAsErrors = Val; }
+ bool getWarningsAsErrors() const { return WarningsAsErrors; }
+
+ /// setWarnOnExtensions - When set to true, issue warnings on GCC extensions,
+ /// the equivalent of GCC's -pedantic.
+ void setWarnOnExtensions(bool Val) { WarnOnExtensions = Val; }
+ bool getWarnOnExtensions() const { return WarnOnExtensions; }
+
+ /// setErrorOnExtensions - When set to true issue errors for GCC extensions
+ /// instead of warnings. This is the equivalent to GCC's -pedantic-errors.
+ void setErrorOnExtensions(bool Val) { ErrorOnExtensions = Val; }
+ bool getErrorOnExtensions() const { return ErrorOnExtensions; }
+
+ /// setDiagnosticMapping - This allows the client to specify that certain
+ /// warnings are ignored. Only NOTEs, WARNINGs, and EXTENSIONs can be mapped.
+ void setDiagnosticMapping(diag::kind Diag, diag::Mapping Map) {
+ assert(isNoteWarningOrExtension(Diag) && "Cannot map errors!");
+ unsigned char &Slot = DiagMappings[Diag/4];
+ unsigned Bits = (Diag & 3)*2;
+ Slot &= ~(3 << Bits);
+ Slot |= Map << Bits;
+ }
+
+ /// getDiagnosticMapping - Return the mapping currently set for the specified
+ /// diagnostic.
+ diag::Mapping getDiagnosticMapping(diag::kind Diag) const {
+ return (diag::Mapping)((DiagMappings[Diag/4] >> (Diag & 3)*2) & 3);
+ }
+
+ bool hasErrorOccurred() const { return ErrorOccurred; }
+
+ unsigned getNumErrors() const { return NumErrors; }
+ unsigned getNumDiagnostics() const { return NumDiagnostics; }
+
+ //===--------------------------------------------------------------------===//
+ // Diagnostic classification and reporting interfaces.
+ //
+
+ /// getDescription - Given a diagnostic ID, return a description of the
+ /// issue.
+ static const char *getDescription(unsigned DiagID);
+
+ /// Level - The level of the diagnostic
+ enum Level {
+ Ignored, Note, Warning, Error, Fatal, Sorry
+ };
+
+ /// isNoteWarningOrExtension - Return true if the unmapped diagnostic level of
+ /// the specified diagnostic ID is a Note, Warning, or Extension.
+ static bool isNoteWarningOrExtension(unsigned DiagID);
+
+ /// getDiagnosticLevel - Based on the way the client configured the Diagnostic
+ /// object, classify the specified diagnostic ID into a Level, consumable by
+ /// the DiagnosticClient.
+ Level getDiagnosticLevel(unsigned DiagID) const;
+
+ /// Report - Issue the message to the client. DiagID is a member of the
+ /// diag::kind enum.
+ void Report(SourceLocation Pos, unsigned DiagID,
+ const std::string *Strs = 0, unsigned NumStrs = 0,
+ const SourceRange *Ranges = 0, unsigned NumRanges = 0);
+};
+
+/// DiagnosticClient - This is an abstract interface implemented by clients of
+/// the front-end, which formats and prints fully processed diagnostics.
+class DiagnosticClient {
+public:
+ virtual ~DiagnosticClient();
+
+ /// IgnoreDiagnostic - If the client wants to ignore this diagnostic, then
+ /// return true.
+ virtual bool IgnoreDiagnostic(Diagnostic::Level DiagLevel,
+ SourceLocation Pos) = 0;
+
+ /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or
+ /// capturing it to a log as needed.
+ virtual void HandleDiagnostic(Diagnostic::Level DiagLevel, SourceLocation Pos,
+ diag::kind ID, const std::string *Strs,
+ unsigned NumStrs, const SourceRange *Ranges,
+ unsigned NumRanges) = 0;
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def
new file mode 100644
index 0000000..8addaa4
--- /dev/null
+++ b/include/clang/Basic/DiagnosticKinds.def
@@ -0,0 +1,668 @@
+//===-- DiagnosticKinds.def - C Family Diagnostic Kind Database -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the DiagnosticKind database.
+//
+//===----------------------------------------------------------------------===//
+
+// Flags for diagnostic:
+//
+// DIAG_TYPE - Allows one of:
+// NOTE - Informational message.
+// WARNING - Warning.
+// EXTENSION - Notification that an extension to the language is being used.
+// ERROR - Error, compilation will stop after parsing completes.
+// FATAL - Fatal error: parsing must stop.
+
+//===----------------------------------------------------------------------===//
+// Portability
+//===----------------------------------------------------------------------===//
+
+DIAG(port_target_macro_use, NOTE,
+ "use of a target-specific macro, source is not 'portable'")
+
+DIAG(port_target_builtin_use, NOTE,
+ "use of a target-specific builtin function, source is not 'portable'")
+
+DIAG(port_wchar_t, NOTE,
+ "sizeof(wchar_t) varies between targets, source is not 'portable'")
+
+//===----------------------------------------------------------------------===//
+// Lexer Diagnostics
+//===----------------------------------------------------------------------===//
+
+DIAG(null_in_string, WARNING,
+ "null character(s) preserved in string literal")
+DIAG(null_in_char , WARNING,
+ "null character(s) preserved in character literal")
+DIAG(null_in_file , WARNING,
+ "null character ignored")
+DIAG(nested_block_comment, WARNING,
+ "\"/*\" within block comment")
+DIAG(escaped_newline_block_comment_end, WARNING,
+ "escaped newline between */ characters at block comment end")
+DIAG(backslash_newline_space, WARNING,
+ "backslash and newline separated by space")
+
+// Trigraphs.
+DIAG(trigraph_ignored, WARNING, "trigraph ignored")
+DIAG(trigraph_ignored_block_comment, WARNING,
+ "ignored trigraph would end block comment")
+DIAG(trigraph_ends_block_comment, WARNING,
+ "trigraph ends block comment")
+DIAG(trigraph_converted, WARNING,
+ "trigraph converted to '%0' character")
+
+DIAG(ext_multi_line_bcpl_comment, EXTENSION,
+ "multi-line // comment")
+DIAG(ext_bcpl_comment, EXTENSION,
+ "// comments are not allowed in this language")
+DIAG(ext_no_newline_eof, EXTENSION,
+ "no newline at end of file")
+DIAG(ext_backslash_newline_eof, EXTENSION,
+ "backslash-newline at end of file")
+DIAG(ext_dollar_in_identifier, EXTENSION,
+ "'$' in identifier")
+DIAG(charize_microsoft_ext, EXTENSION,
+ "@# is a microsoft extension")
+
+DIAG(ext_token_used, EXTENSION,
+ "extension used")
+
+DIAG(err_unterminated_string, ERROR,
+ "missing terminating \" character")
+DIAG(err_unterminated_char, ERROR,
+ "missing terminating ' character")
+DIAG(err_empty_character, ERROR,
+ "empty character constant")
+DIAG(err_unterminated_block_comment, ERROR,
+ "unterminated /* comment")
+DIAG(err_invalid_character_to_charify, ERROR,
+ "invalid argument to convert to character")
+
+//===----------------------------------------------------------------------===//
+// Preprocessor Diagnostics
+//===----------------------------------------------------------------------===//
+
+DIAG(pp_hash_warning, WARNING,
+ "#warning%0")
+DIAG(pp_include_next_in_primary, WARNING,
+ "#include_next in primary source file")
+DIAG(pp_include_next_absolute_path, WARNING,
+ "#include_next with absolute path")
+DIAG(ext_c99_whitespace_required_after_macro_name, WARNING,
+ "ISO C99 requires whitespace after the macro name")
+DIAG(pp_pragma_once_in_main_file, WARNING,
+ "#pragma once in main file")
+DIAG(pp_pragma_sysheader_in_main_file, WARNING,
+ "#pragma system_header ignored in main file")
+DIAG(pp_poisoning_existing_macro, WARNING,
+ "poisoning existing macro")
+DIAG(pp_out_of_date_dependency, WARNING,
+ "current file is older than dependency %0")
+DIAG(pp_undef_builtin_macro, WARNING,
+ "undefining builtin macro")
+DIAG(pp_redef_builtin_macro, WARNING,
+ "redefining builtin macro")
+DIAG(pp_macro_not_used, WARNING, // -Wunused-macros
+ "macro is not used")
+DIAG(pp_invalid_string_literal, WARNING,
+ "invalid string literal, ignoring final '\\'")
+DIAG(warn_pp_expr_overflow, WARNING,
+ "integer overflow in preprocessor expression")
+DIAG(warn_pp_convert_lhs_to_positive, WARNING,
+ "left side of operator converted from negative value to unsigned: %0")
+DIAG(warn_pp_convert_rhs_to_positive, WARNING,
+ "right side of operator converted from negative value to unsigned: %0")
+
+DIAG(ext_pp_import_directive, EXTENSION,
+ "#import is a language extension")
+DIAG(ext_pp_ident_directive, EXTENSION,
+ "#ident is a language extension")
+DIAG(ext_pp_include_next_directive, EXTENSION,
+ "#include_next is a language extension")
+DIAG(ext_pp_warning_directive, EXTENSION,
+ "#warning is a language extension")
+DIAG(ext_pp_extra_tokens_at_eol, EXTENSION,
+ "extra tokens at end of %0 directive")
+DIAG(ext_pp_comma_expr, EXTENSION,
+ "comma operator in operand of #if")
+DIAG(ext_pp_bad_vaargs_use, EXTENSION,
+ "__VA_ARGS__ can only appear in the expansion of a C99 variadic macro")
+DIAG(ext_pp_macro_redef, EXTENSION,
+ "\"%0\" macro redefined")
+DIAG(ext_pp_macro_redef2, EXTENSION,
+ "this is previous definition")
+DIAG(ext_variadic_macro, EXTENSION,
+ "variadic macros were introduced in C99")
+DIAG(ext_named_variadic_macro, EXTENSION,
+ "named variadic macros are a GNU extension")
+DIAG(ext_embedded_directive, EXTENSION,
+ "embedding a directive within macro arguments is not portable")
+DIAG(ext_missing_varargs_arg, EXTENSION,
+ "varargs argument missing, but tolerated as an extension")
+DIAG(ext_empty_fnmacro_arg, EXTENSION,
+ "empty macro arguments were standardized in C99")
+
+DIAG(ext_pp_base_file, EXTENSION,
+ "__BASE_FILE__ is a language extension")
+DIAG(ext_pp_include_level, EXTENSION,
+ "__INCLUDE_LEVEL__ is a language extension")
+DIAG(ext_pp_timestamp, EXTENSION,
+ "__TIMESTAMP__ is a language extension")
+
+DIAG(err_pp_invalid_directive, ERROR,
+ "invalid preprocessing directive")
+DIAG(err_pp_hash_error, ERROR,
+ "#error%0")
+DIAG(err_pp_file_not_found, ERROR,
+ "'%0' file not found")
+DIAG(err_pp_empty_filename, ERROR,
+ "empty filename")
+DIAG(err_pp_include_too_deep, ERROR,
+ "#include nested too deeply")
+DIAG(err_pp_expects_filename, ERROR,
+ "expected \"FILENAME\" or <FILENAME>")
+DIAG(err_pp_macro_not_identifier, ERROR,
+ "macro names must be identifiers")
+DIAG(err_pp_missing_macro_name, ERROR,
+ "macro name missing")
+DIAG(err_pp_missing_rparen_in_macro_def, ERROR,
+ "missing ')' in macro parameter list")
+DIAG(err_pp_invalid_tok_in_arg_list, ERROR,
+ "invalid token in macro parameter list")
+DIAG(err_pp_expected_ident_in_arg_list, ERROR,
+ "expected identifier in macro parameter list")
+DIAG(err_pp_expected_comma_in_arg_list, ERROR,
+ "expected comma in macro parameter list")
+DIAG(err_pp_duplicate_name_in_arg_list, ERROR,
+ "duplicate macro parameter name \"%0\"")
+DIAG(err_pp_stringize_not_parameter, ERROR,
+ "'#' is not followed by a macro parameter")
+DIAG(err_pp_malformed_ident, ERROR,
+ "invalid #ident directive")
+DIAG(err_pp_unterminated_conditional, ERROR,
+ "unterminated conditional directive")
+DIAG(pp_err_else_after_else, ERROR,
+ "#else after #else")
+DIAG(pp_err_elif_after_else, ERROR,
+ "#elif after #else")
+DIAG(pp_err_else_without_if, ERROR,
+ "#else without #if")
+DIAG(pp_err_elif_without_if, ERROR,
+ "#elif without #if")
+DIAG(err_pp_endif_without_if, ERROR,
+ "#endif without #if")
+DIAG(err_pp_expected_value_in_expr, ERROR,
+ "expected value in expression")
+DIAG(err_pp_missing_val_before_operator, ERROR,
+ "missing value before operator")
+DIAG(err_pp_expected_rparen, ERROR,
+ "expected ')' in preprocessor expression")
+DIAG(err_pp_expected_eol, ERROR,
+ "expected end of line in preprocessor expression")
+DIAG(err_pp_defined_requires_identifier, ERROR,
+ "operator \"defined\" requires an identifier")
+DIAG(err_pp_missing_rparen, ERROR,
+ "missing ')' after \"defined\"")
+DIAG(err_pp_colon_without_question, ERROR,
+ "':' without preceding '?'")
+DIAG(err_pp_question_without_colon, ERROR,
+ "'?' without following ':'")
+DIAG(err_pp_division_by_zero, ERROR,
+ "division by zero in preprocessor expression")
+DIAG(err_pp_remainder_by_zero, ERROR,
+ "remainder by zero in preprocessor expression")
+DIAG(err_pp_expr_bad_token, ERROR,
+ "token is not valid in preprocessor expressions")
+DIAG(err_pp_invalid_poison, ERROR,
+ "can only poison identifier tokens")
+DIAG(err_pp_used_poisoned_id, ERROR,
+ "attempt to use a poisoned identifier")
+DIAG(err__Pragma_malformed, ERROR,
+ "_Pragma takes a parenthesized string literal")
+DIAG(err_defined_macro_name, ERROR,
+ "\"defined\" cannot be used as a macro name")
+DIAG(err_paste_at_start, ERROR,
+ "\"##\" cannot appear at start of macro expansion")
+DIAG(err_paste_at_end, ERROR,
+ "\"##\" cannot appear at end of macro expansion")
+DIAG(err_unterm_macro_invoc, ERROR,
+ "unterminated function-like macro invocation")
+DIAG(err_too_many_args_in_macro_invoc, ERROR,
+ "too many arguments provided to function-like macro invocation")
+DIAG(err_too_few_args_in_macro_invoc, ERROR,
+ "too few arguments provided to function-like macro invocation")
+DIAG(err_pp_bad_paste, ERROR,
+ "pasting formed \"%0\", an invalid preprocessing token")
+DIAG(err_pp_operator_used_as_macro_name, ERROR,
+ "C++ operator \"%0\" cannot be used as a macro name")
+DIAG(err_pp_illegal_floating_literal, ERROR,
+ "floating point literal in preprocessor expression")
+
+// Should be a sorry?
+DIAG(err_pp_I_dash_not_supported, ERROR,
+ "-I- not supported, please use -iquote instead")
+
+//===----------------------------------------------------------------------===//
+// Parser Diagnostics
+//===----------------------------------------------------------------------===//
+
+DIAG(w_type_defaults_to_int, WARNING,
+ "type defaults to 'int'")
+DIAG(w_no_declarators, WARNING,
+ "declaration does not declare anything")
+DIAG(w_asm_qualifier_ignored, WARNING,
+ "ignored %0 qualifier on asm")
+
+DIAG(ext_empty_source_file, EXTENSION,
+ "ISO C forbids an empty source file")
+DIAG(ext_top_level_semi, EXTENSION,
+ "ISO C does not allow an extra ';' outside of a function")
+DIAG(ext_extra_struct_semi, EXTENSION,
+ "ISO C does not allow an extra ';' inside a struct or union")
+DIAG(ext_duplicate_declspec, EXTENSION,
+ "duplicate '%0' declaration specifier")
+DIAG(ext_plain_complex, EXTENSION,
+ "ISO C does not support plain '_Complex' meaning '_Complex double'")
+DIAG(ext_integer_complex, EXTENSION,
+ "ISO C does not support complex integer types")
+DIAG(ext_thread_before, EXTENSION,
+ "'__thread' before 'static'")
+
+DIAG(ext_empty_struct_union_enum, EXTENSION,
+ "use of empty %0 extension")
+
+DIAG(ext_ident_list_in_param, EXTENSION,
+ "type-less parameter names in function declaration")
+DIAG(ext_c99_array_usage, EXTENSION,
+ "use of C99-specific array features")
+DIAG(ext_c99_variable_decl_in_for_loop, EXTENSION,
+ "variable declaration in for loop is a C99-specific feature")
+DIAG(ext_c99_compound_literal, EXTENSION,
+ "compound literals are a C99-specific feature")
+DIAG(ext_c99_enumerator_list_comma, EXTENSION,
+ "commas at the end of enumerator lists are a C99-specific feature")
+
+DIAG(ext_gnu_indirect_goto, EXTENSION,
+ "use of GNU indirect-goto extension")
+DIAG(ext_gnu_address_of_label, EXTENSION,
+ "use of GNU address-of-label extension")
+DIAG(ext_gnu_statement_expr, EXTENSION,
+ "use of GNU statement expression extension")
+DIAG(ext_gnu_conditional_expr, EXTENSION,
+ "use of GNU ?: expression extension, eliding middle term")
+DIAG(ext_gnu_empty_initializer, EXTENSION,
+ "use of GNU empty initializer extension")
+DIAG(ext_gnu_array_range, EXTENSION,
+ "use of GNU array range extension")
+DIAG(ext_gnu_missing_equal_designator, EXTENSION,
+ "use of GNU 'missing =' extension in designator")
+DIAG(ext_gnu_old_style_field_designator, EXTENSION,
+ "use of GNU old-style field designator extension")
+DIAG(ext_gnu_case_range, EXTENSION,
+ "use of GNU case range extension")
+
+// Generic errors.
+DIAG(err_parse_error, ERROR,
+ "parse error")
+DIAG(err_expected_expression, ERROR,
+ "expected expression")
+DIAG(err_expected_external_declaration, ERROR,
+ "expected external declaration")
+DIAG(err_expected_ident, ERROR,
+ "expected identifier")
+DIAG(err_expected_ident_lparen, ERROR,
+ "expected identifier or '('")
+DIAG(err_expected_ident_lbrace, ERROR,
+ "expected identifier or '{'")
+DIAG(err_expected_rparen, ERROR,
+ "expected ')'")
+DIAG(err_expected_rsquare, ERROR,
+ "expected ']'")
+DIAG(err_expected_rbrace, ERROR,
+ "expected '}'")
+DIAG(err_expected_greater, ERROR,
+ "expected '>'")
+DIAG(err_expected_semi_decl_list, ERROR,
+ "expected ';' at end of declaration list")
+DIAG(ext_expected_semi_decl_list, EXTENSION,
+ "expected ';' at end of declaration list")
+DIAG(err_expected_fn_body, ERROR,
+ "expected function body after function declarator")
+DIAG(err_expected_after_declarator, ERROR,
+ "expected '=', ',', ';', 'asm', or '__attribute__' after declarator")
+DIAG(err_expected_statement, ERROR,
+ "expected statement")
+DIAG(err_expected_lparen_after, ERROR,
+ "expected '(' after '%0'")
+DIAG(err_expected_less_after, ERROR,
+ "expected '<' after '%0'")
+DIAG(err_expected_comma, ERROR,
+ "expected ','")
+DIAG(err_expected_lbrace_in_compound_literal, ERROR,
+ "expected '{' in compound literal")
+DIAG(err_expected_while, ERROR,
+ "expected 'while' in do/while loop")
+DIAG(err_expected_semi_after, ERROR,
+ "expected ';' after %0")
+DIAG(err_expected_semi_after_expr, ERROR,
+ "expected ';' after expression")
+DIAG(err_expected_semi_for, ERROR,
+ "expected ';' in 'for' statement specifier")
+DIAG(err_expected_colon_after, ERROR,
+ "expected ':' after %0")
+DIAG(err_label_end_of_compound_statement, ERROR,
+ "label at end of compound statement: expected statement")
+DIAG(err_expected_colon, ERROR,
+ "expected ':'")
+DIAG(err_expected_string_literal, ERROR,
+ "expected string literal")
+DIAG(err_expected_asm_operand, ERROR,
+ "expected string literal or '[' for asm operand")
+
+DIAG(err_unexpected_at, ERROR,
+ "unexpected '@' in program")
+
+/// err_matching - this is used as a continuation of a previous error, e.g. to
+/// specify the '(' when we expected a ')'. This should probably be some
+/// special sort of diagnostic kind to indicate that it is the second half of
+/// the previous diagnostic.
+DIAG(err_matching, ERROR,
+ "to match this '%0'")
+
+//===----------------------------------------------------------------------===//
+// Semantic Analysis
+//===----------------------------------------------------------------------===//
+
+// Semantic analysis of string and character constant literals.
+DIAG(ext_nonstandard_escape, EXTENSION,
+ "use of non-standard escape character '\\%0'")
+DIAG(ext_unknown_escape, EXTENSION,
+ "unknown escape sequence '\\%0'")
+DIAG(warn_extraneous_wide_char_constant, WARNING,
+ "extraneous characters in wide character constant ignored")
+DIAG(warn_char_constant_too_large, WARNING,
+ "character constant too long for its type")
+DIAG(warn_hex_escape_too_large, WARNING,
+ "hex escape sequence out of range")
+DIAG(warn_octal_escape_too_large, WARNING,
+ "octal escape sequence out of range")
+
+DIAG(err_hex_escape_no_digits, ERROR,
+ "\\x used with no following hex digits")
+
+// Declarations.
+DIAG(err_typename_requires_specqual, ERROR,
+ "type name requires a specifier or qualifier")
+DIAG(err_typename_invalid_storageclass, ERROR,
+ "type name does not allow storage class to be specified")
+DIAG(err_typename_invalid_functionspec, ERROR,
+ "type name does not allow function specifier to be specified")
+DIAG(err_invalid_decl_spec_combination, ERROR,
+ "cannot combine with previous '%0' declaration specifier")
+DIAG(err_invalid_sign_spec, ERROR,
+ "'%0' cannot be signed or unsigned")
+DIAG(err_invalid_short_spec, ERROR,
+ "'short %0' is invalid")
+DIAG(err_invalid_long_spec, ERROR,
+ "'long %0' is invalid")
+DIAG(err_invalid_longlong_spec, ERROR,
+ "'long long %0' is invalid")
+DIAG(err_invalid_complex_spec, ERROR,
+ "'_Complex %0' is invalid")
+DIAG(err_invalid_thread_spec, ERROR,
+ "'__thread %0' is invalid")
+DIAG(err_ellipsis_first_arg, ERROR,
+ "ISO C requires a named argument before '...'")
+DIAG(err_unspecified_vla_size_with_static, ERROR,
+ "'static' may not be used with an unspecified variable length array size")
+DIAG(err_invalid_storage_class_in_func_decl, ERROR,
+ "invalid storage class specifier in function declarator")
+DIAG(err_invalid_reference_qualifier_application, ERROR,
+ "'%0' qualifier may not be applied to a reference")
+
+// Attributes
+DIAG(err_attribute_wrong_number_arguments, ERROR,
+ "attribute requires %0 argument(s)")
+DIAG(err_attribute_invalid_vector_type, ERROR,
+ "invalid vector type '%0'")
+DIAG(err_attribute_vector_size_not_int, ERROR,
+ "vector_size requires integer constant")
+DIAG(err_attribute_invalid_size, ERROR,
+ "vector size not an integral multiple of component size")
+DIAG(err_attribute_zero_size, ERROR,
+ "zero vector size")
+DIAG(err_typecheck_vector_not_convertable, ERROR,
+ "can't convert between vector values of different size ('%0' and '%1')")
+
+// Function Parameter Semantic Analysis.
+DIAG(err_void_param_with_identifier, ERROR,
+ "void argument may not have a name")
+DIAG(err_void_only_param, ERROR,
+ "'void' must be the first and only parameter if specified")
+DIAG(err_void_param_qualified, ERROR,
+ "'void' as parameter must not have type qualifiers")
+DIAG(err_param_redefinition, ERROR,
+ "redefinition of parameter '%0'")
+DIAG(err_ident_list_in_fn_declaration, ERROR,
+ "a parameter list without types is only allowed in a function definition")
+DIAG(err_declaration_does_not_declare_param, ERROR,
+ "declaration does not declare a parameter")
+DIAG(err_no_matching_param, ERROR,
+ "parameter named '%0' is missing")
+DIAG(ext_param_not_declared, EXTENSION,
+ "parameter '%0' was not declared, defaulting to type 'int'")
+
+DIAG(err_previous_definition, ERROR,
+ "previous definition is here")
+DIAG(err_previous_use, ERROR,
+ "previous use is here")
+
+DIAG(err_unexpected_typedef, ERROR,
+ "unexpected type name '%0': expected expression")
+DIAG(err_undeclared_var_use, ERROR,
+ "use of undeclared identifier '%0'")
+DIAG(err_redefinition, ERROR,
+ "redefinition of '%0'")
+DIAG(err_redefinition_different_kind, ERROR,
+ "redefinition of '%0' as different kind of symbol")
+DIAG(err_nested_redefinition, ERROR,
+ "nested redefinition of '%0'")
+DIAG(err_use_with_wrong_tag, ERROR,
+ "use of '%0' with tag type that does not match previous declaration")
+DIAG(ext_forward_ref_enum, EXTENSION,
+ "ISO C forbids forward references to 'enum' types")
+DIAG(err_redefinition_of_enumerator, ERROR,
+ "redefinition of enumerator '%0'")
+DIAG(err_duplicate_member, ERROR,
+ "duplicate member '%0'")
+DIAG(err_enum_value_not_integer_constant_expr, ERROR,
+ "enumerator value for '%0' is not an integer constant")
+DIAG(err_case_label_not_integer_constant_expr, ERROR,
+ "case label does not reduce to an integer constant")
+DIAG(err_typecheck_illegal_vla, ERROR,
+ "variable length array declared outside of any function")
+DIAG(err_typecheck_negative_array_size, ERROR,
+ "array size is negative")
+DIAG(err_typecheck_zero_array_size, EXTENSION,
+ "zero size arrays are an extension")
+DIAG(err_array_size_non_int, ERROR,
+ "size of array has non-integer type '%0'")
+
+DIAG(err_redefinition_of_label, ERROR,
+ "redefinition of label '%0'")
+DIAG(err_undeclared_label_use, ERROR,
+ "use of undeclared label '%0'")
+
+DIAG(warn_implicit_function_decl, WARNING,
+ "implicit declaration of function '%0'")
+DIAG(ext_implicit_function_decl, EXTENSION,
+ "implicit declaration of function '%0' is invalid in C99")
+
+DIAG(err_field_declared_as_function, ERROR,
+ "field '%0' declared as a function")
+DIAG(err_field_incomplete, ERROR,
+ "field '%0' has incomplete type")
+DIAG(err_variable_sized_type_in_struct, EXTENSION,
+ "variable sized type '%0' must be at end of struct or class")
+DIAG(err_flexible_array_empty_struct, ERROR,
+ "flexible array '%0' not allowed in otherwise empty struct")
+DIAG(ext_flexible_array_in_struct, EXTENSION,
+ "'%0' may not be nested in a struct due to flexible array member")
+DIAG(err_flexible_array_in_array, ERROR,
+ "'%0' may not be used as an array element due to flexible array member")
+DIAG(err_illegal_decl_array_of_functions, ERROR,
+ "'%0' declared as array of functions")
+DIAG(err_illegal_decl_array_incomplete_type, ERROR,
+ "array has incomplete element type '%0'")
+DIAG(err_illegal_decl_array_of_references, ERROR,
+ "'%0' declared as array of references")
+DIAG(err_illegal_decl_pointer_to_reference, ERROR,
+ "'%0' declared as a pointer to a reference")
+DIAG(err_illegal_decl_reference_to_reference, ERROR,
+ "'%0' declared as a reference to a reference")
+
+// Expressions.
+DIAG(ext_sizeof_function_type, EXTENSION,
+ "invalid application of 'sizeof' to a function type")
+DIAG(ext_sizeof_void_type, EXTENSION,
+ "invalid application of '%0' to a void type")
+DIAG(err_sizeof_incomplete_type, ERROR,
+ "invalid application of 'sizeof' to an incomplete type '%0'")
+DIAG(err_alignof_incomplete_type, ERROR,
+ "invalid application of '__alignof' to an incomplete type '%0'")
+DIAG(err_invalid_suffix_integer_constant, ERROR,
+ "invalid suffix '%0' on integer constant")
+DIAG(err_invalid_suffix_float_constant, ERROR,
+ "invalid suffix '%0' on floating constant")
+DIAG(warn_integer_too_large, WARNING,
+ "integer constant is too large for its type")
+DIAG(warn_integer_too_large_for_signed, WARNING,
+ "integer constant is so large that it is unsigned")
+DIAG(err_exponent_has_no_digits, ERROR,
+ "exponent has no digits")
+DIAG(ext_binary_literal, EXTENSION,
+ "binary integer literals are an extension")
+DIAG(err_invalid_binary_digit, ERROR,
+ "invalid digit '%0' in binary constant")
+DIAG(err_invalid_octal_digit, ERROR,
+ "invalid digit '%0' in octal constant")
+DIAG(err_invalid_decimal_digit, ERROR,
+ "invalid digit '%0' in decimal constant")
+DIAG(err_hexconstant_requires_exponent, ERROR,
+ "hexadecimal floating constants require an exponent")
+DIAG(err_typecheck_subscript_value, ERROR,
+ "subscripted value is neither array nor pointer")
+DIAG(err_typecheck_subscript, ERROR,
+ "array subscript is not an integer")
+DIAG(err_typecheck_subscript_not_object, ERROR,
+ "illegal subscript of non-object type '%0'")
+DIAG(err_typecheck_member_reference_structUnion, ERROR,
+ "member reference is not to a structure or union")
+DIAG(err_typecheck_member_reference_arrow, ERROR,
+ "member reference is not a pointer")
+DIAG(err_typecheck_incomplete_tag, ERROR,
+ "incomplete definition of type '%0'")
+DIAG(err_typecheck_no_member, ERROR,
+ "no member named '%0'")
+DIAG(err_typecheck_illegal_increment_decrement, ERROR,
+ "cannot modify value of type '%0'")
+DIAG(err_typecheck_invalid_lvalue_incr_decr, ERROR,
+ "invalid lvalue in increment/decrement expression")
+DIAG(err_typecheck_arithmetic_incomplete_type, ERROR,
+ "arithmetic on pointer to incomplete type '%0'")
+DIAG(err_typecheck_decl_incomplete_type, ERROR,
+ "variable has incomplete type '%0'")
+DIAG(err_typecheck_sclass_fscope, ERROR,
+ "illegal storage class on file-scoped variable")
+DIAG(err_typecheck_sclass_func, ERROR,
+ "illegal storage class on function")
+DIAG(err_typecheck_address_of_register, ERROR,
+ "address of register variable requested")
+DIAG(err_typecheck_invalid_lvalue_addrof, ERROR,
+ "invalid lvalue in address expression")
+DIAG(err_typecheck_unary_expr, ERROR,
+ "invalid argument type to unary expression '%0'")
+DIAG(err_typecheck_indirection_requires_pointer, ERROR,
+ "indirection requires pointer operand ('%0' invalid)")
+DIAG(err_typecheck_deref_incomplete_type, ERROR,
+ "dereferencing pointer to incomplete type '%0'")
+DIAG(ext_typecheck_deref_ptr_to_void, EXTENSION,
+ "dereferencing '%0' pointer")
+DIAG(err_typecheck_invalid_operands, ERROR,
+ "invalid operands to binary expression ('%0' and '%1')")
+DIAG(ext_typecheck_comparison_of_pointer_integer, EXTENSION,
+ "comparison between pointer and integer")
+DIAG(err_typecheck_assign_const, ERROR,
+ "read-only variable is not assignable")
+DIAG(err_typecheck_assign_incompatible, ERROR,
+ "incompatible types assigning '%1' to '%0'")
+DIAG(ext_typecheck_assign_pointer_int, EXTENSION,
+ "incompatible types assigning '%1' to '%0'")
+DIAG(ext_typecheck_assign_incompatible_pointer, EXTENSION,
+ "incompatible pointer types assigning '%1' to '%0'")
+DIAG(ext_typecheck_assign_discards_qualifiers, EXTENSION,
+ "assigning '%1' to '%0' discards qualifiers")
+DIAG(err_typecheck_array_not_modifiable_lvalue, ERROR,
+ "array type '%0' is not assignable")
+DIAG(err_typecheck_non_object_not_modifiable_lvalue, ERROR,
+ "non-object type '%0' is not assignable")
+DIAG(err_typecheck_expression_not_modifiable_lvalue, ERROR,
+ "expression is not assignable")
+DIAG(err_typecheck_incomplete_type_not_modifiable_lvalue, ERROR,
+ "incomplete type '%0' is not assignable")
+DIAG(err_typecheck_call_not_function, ERROR,
+ "called object is not a function or function pointer")
+DIAG(err_typecheck_call_too_few_args, ERROR,
+ "too few arguments to function")
+DIAG(err_typecheck_call_too_many_args, ERROR,
+ "too many arguments to function")
+DIAG(err_typecheck_passing_incompatible, ERROR,
+ "incompatible types passing '%0' to function expecting '%1'")
+DIAG(ext_typecheck_passing_incompatible_pointer, EXTENSION,
+ "incompatible pointer types passing '%0' to function expecting '%1'")
+DIAG(ext_typecheck_passing_pointer_int, EXTENSION,
+ "incompatible types passing '%1' to function expecting '%0'")
+DIAG(ext_typecheck_passing_discards_qualifiers, EXTENSION,
+ "passing '%0' to '%1' discards qualifiers")
+DIAG(err_typecheck_cond_expect_scalar, ERROR,
+ "used type '%0' where arithmetic or pointer type is required")
+DIAG(err_typecheck_cond_incompatible_operands, ERROR,
+ "incompatible operand types ('%0' and '%1')")
+DIAG(ext_typecheck_cond_incompatible_pointers, EXTENSION,
+ "pointer type mismatch ('%0' and '%1')")
+
+DIAG(warn_unused_expr, WARNING,
+ "expression result unused")
+
+// Statements.
+DIAG(err_continue_not_in_loop, ERROR,
+ "'continue' statement not in loop statement")
+DIAG(err_break_not_in_loop_or_switch, ERROR,
+ "'break' statement not in loop or switch statement")
+DIAG(err_typecheck_return_incompatible, ERROR,
+ "incompatible type returning '%1', expected '%0'")
+DIAG(ext_typecheck_return_pointer_int, EXTENSION,
+ "incompatible type returning '%1', expected '%0'")
+DIAG(ext_typecheck_return_incompatible_pointer, EXTENSION,
+ "incompatible pointer type returning '%1', expected '%0'")
+DIAG(ext_typecheck_return_discards_qualifiers, EXTENSION,
+ "returning '%1' from function expecting '%0' discards qualifiers")
+DIAG(err_typecheck_statement_requires_scalar, ERROR,
+ "statement requires expression of scalar type ('%0' invalid)")
+
+DIAG(warn_return_missing_expr, WARNING,
+ "non-void function '%0' should return a value")
+DIAG(ext_return_missing_expr, EXTENSION,
+ "non-void function '%0' should return a value")
+DIAG(ext_return_has_expr, EXTENSION,
+ "void function '%0' should not return a value")
+
+#undef DIAG
diff --git a/include/clang/Basic/FileManager.h b/include/clang/Basic/FileManager.h
new file mode 100644
index 0000000..ad955d7
--- /dev/null
+++ b/include/clang/Basic/FileManager.h
@@ -0,0 +1,111 @@
+//===--- FileManager.h - File System Probing and Caching --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the FileManager interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FILEMANAGER_H
+#define LLVM_CLANG_FILEMANAGER_H
+
+#include "llvm/ADT/StringMap.h"
+#include <map>
+#include <string>
+// FIXME: Enhance libsystem to support inode and other fields in stat.
+#include <sys/types.h>
+
+namespace clang {
+class FileManager;
+
+/// DirectoryEntry - Cached information about one directory on the disk.
+///
+class DirectoryEntry {
+ const char *Name; // Name of the directory.
+ friend class FileManager;
+public:
+ DirectoryEntry() : Name(0) {}
+ const char *getName() const { return Name; }
+};
+
+/// FileEntry - Cached information about one file on the disk.
+///
+class FileEntry {
+ const char *Name; // Name of the directory.
+ off_t Size; // File size in bytes.
+ time_t ModTime; // Modification time of file.
+ const DirectoryEntry *Dir; // Directory file lives in.
+ unsigned UID; // A unique (small) ID for the file.
+ friend class FileManager;
+public:
+ FileEntry() : Name(0) {}
+
+ const char *getName() const { return Name; }
+ off_t getSize() const { return Size; }
+ unsigned getUID() const { return UID; }
+ time_t getModificationTime() const { return ModTime; }
+
+ /// getDir - Return the directory the file lives in.
+ ///
+ const DirectoryEntry *getDir() const { return Dir; }
+};
+
+
+/// FileManager - Implements support for file system lookup, file system
+/// caching, and directory search management. This also handles more advanced
+/// properties, such as uniquing files based on "inode", so that a file with two
+/// names (e.g. symlinked) will be treated as a single file.
+///
+class FileManager {
+ /// UniqueDirs/UniqueFiles - Cache from ID's to existing directories/files.
+ ///
+ std::map<std::pair<dev_t, ino_t>, DirectoryEntry> UniqueDirs;
+ std::map<std::pair<dev_t, ino_t>, FileEntry> UniqueFiles;
+
+ /// DirEntries/FileEntries - This is a cache of directory/file entries we have
+ /// looked up. The actual Entry is owned by UniqueFiles/UniqueDirs above.
+ ///
+ llvm::StringMap<DirectoryEntry*> DirEntries;
+ llvm::StringMap<FileEntry*> FileEntries;
+
+ /// NextFileUID - Each FileEntry we create is assigned a unique ID #.
+ ///
+ unsigned NextFileUID;
+
+ // Statistics.
+ unsigned NumDirLookups, NumFileLookups;
+ unsigned NumDirCacheMisses, NumFileCacheMisses;
+public:
+ FileManager() : DirEntries(64), FileEntries(64), NextFileUID(0) {
+ NumDirLookups = NumFileLookups = 0;
+ NumDirCacheMisses = NumFileCacheMisses = 0;
+ }
+
+ /// getDirectory - Lookup, cache, and verify the specified directory. This
+ /// returns null if the directory doesn't exist.
+ ///
+ const DirectoryEntry *getDirectory(const std::string &Filename) {
+ return getDirectory(&Filename[0], &Filename[0] + Filename.size());
+ }
+ const DirectoryEntry *getDirectory(const char *FileStart,const char *FileEnd);
+
+ /// getFile - Lookup, cache, and verify the specified file. This returns null
+ /// if the file doesn't exist.
+ ///
+ const FileEntry *getFile(const std::string &Filename) {
+ return getFile(&Filename[0], &Filename[0] + Filename.size());
+ }
+ const FileEntry *getFile(const char *FilenameStart,
+ const char *FilenameEnd);
+
+ void PrintStats() const;
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h
new file mode 100644
index 0000000..37a5e73
--- /dev/null
+++ b/include/clang/Basic/LangOptions.h
@@ -0,0 +1,44 @@
+//===--- LangOptions.h - C Language Family Language Options -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the LangOptions interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LANGOPTIONS_H
+#define LLVM_CLANG_LANGOPTIONS_H
+
+namespace clang {
+
+/// LangOptions - This class keeps track of the various options that can be
+/// enabled, which controls the dialect of C that is accepted.
+struct LangOptions {
+ unsigned Trigraphs : 1; // Trigraphs in source files.
+ unsigned BCPLComment : 1; // BCPL-style // comments.
+ unsigned DollarIdents : 1; // '$' allowed in identifiers.
+ unsigned Digraphs : 1; // When added to C? C99?
+ unsigned HexFloats : 1; // C99 Hexadecimal float constants.
+ unsigned C99 : 1; // C99 Support
+ unsigned Microsoft : 1; // Microsoft extensions.
+ unsigned CPlusPlus : 1; // C++ Support
+ unsigned NoExtensions : 1; // All extensions are disabled, strict mode.
+ unsigned CXXOperatorNames : 1; // Treat C++ operator names as keywords.
+
+ unsigned ObjC1 : 1; // Objective C 1 support enabled.
+ unsigned ObjC2 : 1; // Objective C 2 support enabled.
+
+ LangOptions() {
+ Trigraphs = BCPLComment = DollarIdents = Digraphs = ObjC1 = ObjC2 = 0;
+ C99 = Microsoft = CPlusPlus = NoExtensions = CXXOperatorNames = 0;
+ }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/SourceLocation.h b/include/clang/Basic/SourceLocation.h
new file mode 100644
index 0000000..1a90da9
--- /dev/null
+++ b/include/clang/Basic/SourceLocation.h
@@ -0,0 +1,108 @@
+//===--- SourceLocation.h - Compact identifier for Source Files -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the SourceLocation class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SOURCELOCATION_H
+#define LLVM_CLANG_SOURCELOCATION_H
+
+namespace clang {
+
+/// SourceLocation - This is a carefully crafted 32-bit identifier that encodes
+/// a full include stack, line and column number information for a position in
+/// an input translation unit.
+class SourceLocation {
+ unsigned ID;
+public:
+ enum {
+ FileIDBits = 14,
+ FilePosBits = 32-FileIDBits
+ };
+
+ SourceLocation() : ID(0) {} // 0 is an invalid FileID.
+
+ /// SourceLocation constructor - Create a new SourceLocation object with the
+ /// specified FileID and FilePos.
+ SourceLocation(unsigned FileID, unsigned FilePos) {
+ // If a FilePos is larger than (1<<FilePosBits), the SourceManager makes
+ // enough consequtive FileIDs that we have one for each chunk.
+ if (FilePos >= (1 << FilePosBits)) {
+ FileID += FilePos >> FilePosBits;
+ FilePos &= (1 << FilePosBits)-1;
+ }
+
+ // FIXME: Find a way to handle out of FileID bits! Maybe MaxFileID is an
+ // escape of some sort?
+ if (FileID >= (1 << FileIDBits))
+ FileID = (1 << FileIDBits)-1;
+
+ ID = (FileID << FilePosBits) | FilePos;
+ }
+
+ /// isValid - Return true if this is a valid SourceLocation object. Invalid
+ /// SourceLocations are often used when events have no corresponding location
+ /// in the source (e.g. a diagnostic is required for a command line option).
+ ///
+ bool isValid() const { return ID != 0; }
+
+ /// getFileID - Return the file identifier for this SourceLocation. This
+ /// FileID can be used with the SourceManager object to obtain an entire
+ /// include stack for a file position reference.
+ unsigned getFileID() const { return ID >> FilePosBits; }
+
+ /// getRawFilePos - Return the byte offset from the start of the file-chunk
+ /// referred to by FileID. This method should not be used to get the offset
+ /// from the start of the file, instead you should use
+ /// SourceManager::getFilePos. This method will be incorrect for large files.
+ unsigned getRawFilePos() const { return ID & ((1 << FilePosBits)-1); }
+
+
+ /// getRawEncoding - When a SourceLocation itself cannot be used, this returns
+ /// an (opaque) 32-bit integer encoding for it. This should only be passed
+ /// to SourceLocation::getFromRawEncoding, it should not be inspected
+ /// directly.
+ unsigned getRawEncoding() const { return ID; }
+
+ /// getFromRawEncoding - Turn a raw encoding of a SourceLocation object into
+ /// a real SourceLocation.
+ static SourceLocation getFromRawEncoding(unsigned Encoding) {
+ SourceLocation X;
+ X.ID = Encoding;
+ return X;
+ }
+};
+
+inline bool operator==(const SourceLocation &LHS, const SourceLocation &RHS) {
+ return LHS.getRawEncoding() == RHS.getRawEncoding();
+}
+
+inline bool operator!=(const SourceLocation &LHS, const SourceLocation &RHS) {
+ return !(LHS == RHS);
+}
+
+/// SourceRange - a trival tuple used to represent a source range.
+class SourceRange {
+ SourceLocation B;
+ SourceLocation E;
+public:
+ SourceRange(): B(SourceLocation()), E(SourceLocation()) {}
+ SourceRange(SourceLocation loc) : B(loc), E(loc) {}
+ SourceRange(SourceLocation begin, SourceLocation end) : B(begin), E(end) {}
+
+ SourceLocation Begin() const { return B; }
+ SourceLocation End() const { return E; }
+
+ bool isValid() const { return B.isValid() && E.isValid(); }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h
new file mode 100644
index 0000000..ef0ac0b
--- /dev/null
+++ b/include/clang/Basic/SourceManager.h
@@ -0,0 +1,341 @@
+//===--- SourceManager.h - Track and cache source files ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the SourceManager interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SOURCEMANAGER_H
+#define LLVM_CLANG_SOURCEMANAGER_H
+
+#include "clang/Basic/SourceLocation.h"
+#include <vector>
+#include <map>
+#include <list>
+
+namespace llvm {
+class MemoryBuffer;
+}
+
+namespace clang {
+
+class SourceManager;
+class FileEntry;
+class IdentifierTokenInfo;
+
+/// SrcMgr - Private classes that are part of the SourceManager implementation.
+///
+namespace SrcMgr {
+ /// FileInfo - Once instance of this struct is kept for every file loaded or
+ /// used. This object owns the MemoryBuffer object.
+ struct FileInfo {
+ /// Buffer - The actual buffer containing the characters from the input
+ /// file.
+ const llvm::MemoryBuffer *Buffer;
+
+ /// SourceLineCache - A new[]'d array of offsets for each source line. This
+ /// is lazily computed.
+ ///
+ unsigned *SourceLineCache;
+
+ /// NumLines - The number of lines in this FileInfo. This is only valid if
+ /// SourceLineCache is non-null.
+ unsigned NumLines;
+ };
+
+ typedef std::pair<const FileEntry * const, FileInfo> InfoRec;
+
+ /// FileIDInfo - Information about a FileID, basically just the logical file
+ /// that it represents and include stack information. A SourceLocation is a
+ /// byte offset from the start of this.
+ ///
+ /// FileID's are used to compute the location of a character in memory as well
+ /// as the logical source location, which can be differ from the physical
+ /// location. It is different when #line's are active or when macros have
+ /// been expanded.
+ ///
+ /// Each FileID has include stack information, indicating where it came from.
+ /// For the primary translation unit, it comes from SourceLocation() aka 0.
+ ///
+ /// There are three types of FileID's:
+ /// 1. Normal MemoryBuffer (file). These are represented by a "InfoRec *",
+ /// describing the source file, and a Chunk number, which factors into
+ /// the SourceLocation's offset from the start of the buffer.
+ /// 2. Macro Expansions. These indicate that the logical location is
+ /// totally different than the physical location. The logical source
+ /// location is specified by the IncludeLoc. The physical location is
+ /// the FilePos of the token's SourceLocation combined with the FileID
+ /// from MacroTokenFileID.
+ ///
+ struct FileIDInfo {
+ enum FileIDType {
+ NormalBuffer,
+ MacroExpansion
+ };
+
+ /// The type of this FileID.
+ FileIDType IDType;
+
+ /// IncludeLoc - The location of the #include that brought in this file.
+ /// This SourceLocation object has a FileId of 0 for the main file.
+ SourceLocation IncludeLoc;
+
+ /// This union is discriminated by IDType.
+ ///
+ union {
+ struct NormalBufferInfo {
+ /// ChunkNo - Really large buffers are broken up into chunks that are
+ /// each (1 << SourceLocation::FilePosBits) in size. This specifies the
+ /// chunk number of this FileID.
+ unsigned ChunkNo;
+
+ /// FileInfo - Information about the source buffer itself.
+ ///
+ const InfoRec *Info;
+ } NormalBuffer;
+
+ /// MacroTokenFileID - This is the File ID that contains the characters
+ /// that make up the expanded token.
+ unsigned MacroTokenFileID;
+ } u;
+
+ /// getNormalBuffer - Return a FileIDInfo object for a normal buffer
+ /// reference.
+ static FileIDInfo getNormalBuffer(SourceLocation IL, unsigned CN,
+ const InfoRec *Inf) {
+ FileIDInfo X;
+ X.IDType = NormalBuffer;
+ X.IncludeLoc = IL;
+ X.u.NormalBuffer.ChunkNo = CN;
+ X.u.NormalBuffer.Info = Inf;
+ return X;
+ }
+
+ /// getMacroExpansion - Return a FileID for a macro expansion. IL specifies
+ /// the instantiation location, and MacroFID specifies the FileID that the
+ /// token's characters come from.
+ static FileIDInfo getMacroExpansion(SourceLocation IL,
+ unsigned MacroFID) {
+ FileIDInfo X;
+ X.IDType = MacroExpansion;
+ X.IncludeLoc = IL;
+ X.u.MacroTokenFileID = MacroFID;
+ return X;
+ }
+
+ unsigned getNormalBufferChunkNo() const {
+ assert(IDType == NormalBuffer && "Not a normal buffer!");
+ return u.NormalBuffer.ChunkNo;
+ }
+
+ const InfoRec *getNormalBufferInfo() const {
+ assert(IDType == NormalBuffer && "Not a normal buffer!");
+ return u.NormalBuffer.Info;
+ }
+ };
+} // end SrcMgr namespace.
+
+
+/// SourceManager - This file handles loading and caching of source files into
+/// memory. This object owns the MemoryBuffer objects for all of the loaded
+/// files and assigns unique FileID's for each unique #include chain.
+///
+/// The SourceManager can be queried for information about SourceLocation
+/// objects, turning them into either physical or logical locations. Physical
+/// locations represent where the bytes corresponding to a token came from and
+/// logical locations represent where the location is in the user's view. In
+/// the case of a macro expansion, for example, the physical location indicates
+/// where the expanded token came from and the logical location specifies where
+/// it was expanded. Logical locations are also influenced by #line directives,
+/// etc.
+class SourceManager {
+ /// FileInfos - Memoized information about all of the files tracked by this
+ /// SourceManager.
+ std::map<const FileEntry *, SrcMgr::FileInfo> FileInfos;
+
+ /// MemBufferInfos - Information about various memory buffers that we have
+ /// read in. This is a list, instead of a vector, because we need pointers to
+ /// the FileInfo objects to be stable.
+ std::list<SrcMgr::InfoRec> MemBufferInfos;
+
+ /// FileIDs - Information about each FileID. FileID #0 is not valid, so all
+ /// entries are off by one.
+ std::vector<SrcMgr::FileIDInfo> FileIDs;
+
+ /// LastInstantiationLoc_* - Cache the last instantiation request for fast
+ /// lookup. Macros often want many tokens instantated at the same location.
+ SourceLocation LastInstantiationLoc_InstantLoc;
+ unsigned LastInstantiationLoc_MacroFID;
+ unsigned LastInstantiationLoc_Result;
+public:
+ SourceManager() { LastInstantiationLoc_MacroFID = ~0U; }
+ ~SourceManager();
+
+ /// createFileID - Create a new FileID that represents the specified file
+ /// being #included from the specified IncludePosition. This returns 0 on
+ /// error and translates NULL into standard input.
+ unsigned createFileID(const FileEntry *SourceFile, SourceLocation IncludePos){
+ const SrcMgr::InfoRec *IR = getInfoRec(SourceFile);
+ if (IR == 0) return 0; // Error opening file?
+ return createFileID(IR, IncludePos);
+ }
+
+ /// createFileIDForMemBuffer - Create a new FileID that represents the
+ /// specified memory buffer. This does no caching of the buffer and takes
+ /// ownership of the MemoryBuffer, so only pass a MemoryBuffer to this once.
+ unsigned createFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer) {
+ return createFileID(createMemBufferInfoRec(Buffer), SourceLocation());
+ }
+
+ /// getInstantiationLoc - Return a new SourceLocation that encodes the fact
+ /// that a token from physloc PhysLoc should actually be referenced from
+ /// InstantiationLoc.
+ SourceLocation getInstantiationLoc(SourceLocation PhysLoc,
+ SourceLocation InstantiationLoc);
+
+ /// getBuffer - Return the buffer for the specified FileID.
+ ///
+ const llvm::MemoryBuffer *getBuffer(unsigned FileID) const {
+ return getFileInfo(FileID)->Buffer;
+ }
+
+ /// getIncludeLoc - Return the location of the #include for the specified
+ /// FileID.
+ SourceLocation getIncludeLoc(unsigned FileID) const;
+
+ /// getFilePos - This (efficient) method returns the offset from the start of
+ /// the file that the specified SourceLocation represents. This returns the
+ /// location of the physical character data, not the logical file position.
+ unsigned getFilePos(SourceLocation Loc) const {
+ const SrcMgr::FileIDInfo *FIDInfo = getFIDInfo(Loc.getFileID());
+
+ // For Macros, the physical loc is specified by the MacroTokenFileID.
+ if (FIDInfo->IDType == SrcMgr::FileIDInfo::MacroExpansion)
+ FIDInfo = &FileIDs[FIDInfo->u.MacroTokenFileID-1];
+
+ // If this file has been split up into chunks, factor in the chunk number
+ // that the FileID references.
+ unsigned ChunkNo = FIDInfo->getNormalBufferChunkNo();
+ return Loc.getRawFilePos() + (ChunkNo << SourceLocation::FilePosBits);
+ }
+
+ /// getCharacterData - Return a pointer to the start of the specified location
+ /// in the appropriate MemoryBuffer.
+ const char *getCharacterData(SourceLocation SL) const;
+
+ /// getColumnNumber - Return the column # for the specified include position.
+ /// this is significantly cheaper to compute than the line number. This
+ /// returns zero if the column number isn't known.
+ unsigned getColumnNumber(SourceLocation Loc) const;
+
+ /// getLineNumber - Given a SourceLocation, return the physical line number
+ /// for the position indicated. This requires building and caching a table of
+ /// line offsets for the MemoryBuffer, so this is not cheap: use only when
+ /// about to emit a diagnostic.
+ unsigned getLineNumber(SourceLocation Loc);
+
+ /// getSourceFilePos - This method returns the *logical* offset from the start
+ /// of the file that the specified SourceLocation represents. This returns
+ /// the location of the *logical* character data, not the physical file
+ /// position. In the case of macros, for example, this returns where the
+ /// macro was instantiated, not where the characters for the macro can be
+ /// found.
+ unsigned getSourceFilePos(SourceLocation Loc) const;
+
+ /// getSourceName - This method returns the name of the file or buffer that
+ /// the SourceLocation specifies. This can be modified with #line directives,
+ /// etc.
+ std::string getSourceName(SourceLocation Loc);
+
+ /// getFileEntryForFileID - Return the FileEntry record for the specified
+ /// FileID if one exists.
+ const FileEntry *getFileEntryForFileID(unsigned FileID) const {
+ assert(FileID-1 < FileIDs.size() && "Invalid FileID!");
+ return FileIDs[FileID-1].getNormalBufferInfo()->first;
+ }
+
+ /// Given a SourceLocation object, return the logical location referenced by
+ /// the ID. This logical location is subject to #line directives, etc.
+ SourceLocation getLogicalLoc(SourceLocation Loc) const {
+ if (Loc.getFileID() == 0) return Loc;
+
+ const SrcMgr::FileIDInfo *FIDInfo = getFIDInfo(Loc.getFileID());
+ if (FIDInfo->IDType == SrcMgr::FileIDInfo::MacroExpansion)
+ return FIDInfo->IncludeLoc;
+ return Loc;
+ }
+
+ /// getPhysicalLoc - Given a SourceLocation object, return the physical
+ /// location referenced by the ID.
+ SourceLocation getPhysicalLoc(SourceLocation Loc) const {
+ if (Loc.getFileID() == 0) return Loc;
+
+ // For Macros, the physical loc is specified by the MacroTokenFileID.
+ const SrcMgr::FileIDInfo *FIDInfo = getFIDInfo(Loc.getFileID());
+ if (FIDInfo->IDType == SrcMgr::FileIDInfo::MacroExpansion)
+ return SourceLocation(FIDInfo->u.MacroTokenFileID,
+ Loc.getRawFilePos());
+ return Loc;
+ }
+
+ /// PrintStats - Print statistics to stderr.
+ ///
+ void PrintStats() const;
+private:
+ /// createFileID - Create a new fileID for the specified InfoRec and include
+ /// position. This works regardless of whether the InfoRec corresponds to a
+ /// file or some other input source.
+ unsigned createFileID(const SrcMgr::InfoRec *File, SourceLocation IncludePos);
+
+ /// getInfoRec - Create or return a cached FileInfo for the specified file.
+ /// This returns null on failure.
+ const SrcMgr::InfoRec *getInfoRec(const FileEntry *SourceFile);
+
+ /// createMemBufferInfoRec - Create a new info record for the specified memory
+ /// buffer. This does no caching.
+ const SrcMgr::InfoRec *createMemBufferInfoRec(const llvm::MemoryBuffer *Buf);
+
+ const SrcMgr::FileIDInfo *getFIDInfo(unsigned FileID) const {
+ assert(FileID-1 < FileIDs.size() && "Invalid FileID!");
+ return &FileIDs[FileID-1];
+ }
+
+ /// Return the InfoRec structure for the specified FileID. This is always the
+ /// physical reference for the ID.
+ const SrcMgr::InfoRec *getInfoRec(const SrcMgr::FileIDInfo *FIDInfo) const {
+ // For Macros, the physical loc is specified by the MacroTokenFileID.
+ if (FIDInfo->IDType == SrcMgr::FileIDInfo::MacroExpansion)
+ FIDInfo = &FileIDs[FIDInfo->u.MacroTokenFileID-1];
+ return FIDInfo->getNormalBufferInfo();
+ }
+ const SrcMgr::InfoRec *getInfoRec(unsigned FileID) const {
+ return getInfoRec(getFIDInfo(FileID));
+ }
+
+ SrcMgr::FileInfo *getFileInfo(const SrcMgr::FileIDInfo *FIDInfo) const {
+ if (const SrcMgr::InfoRec *IR = getInfoRec(FIDInfo))
+ return const_cast<SrcMgr::FileInfo *>(&IR->second);
+ return 0;
+ }
+ SrcMgr::FileInfo *getFileInfo(unsigned FileID) const {
+ if (const SrcMgr::InfoRec *IR = getInfoRec(FileID))
+ return const_cast<SrcMgr::FileInfo *>(&IR->second);
+ return 0;
+ }
+ SrcMgr::FileInfo *getFileInfo(const FileEntry *SourceFile) {
+ if (const SrcMgr::InfoRec *IR = getInfoRec(SourceFile))
+ return const_cast<SrcMgr::FileInfo *>(&IR->second);
+ return 0;
+ }
+};
+
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
new file mode 100644
index 0000000..17fa86b
--- /dev/null
+++ b/include/clang/Basic/TargetInfo.h
@@ -0,0 +1,208 @@
+//===--- TargetInfo.h - Expose information about the target -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the TargetInfo and TargetInfoImpl interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_TARGETINFO_H
+#define LLVM_CLANG_BASIC_TARGETINFO_H
+
+#include "clang/Basic/SourceLocation.h"
+#include <vector>
+#include <string>
+
+namespace clang {
+
+class TargetInfoImpl;
+class Diagnostic;
+namespace Builtin { struct Info; }
+
+/// TargetInfo - This class exposes information about the current target set.
+/// A target set consists of a primary target and zero or more secondary targets
+/// which are each represented by a TargetInfoImpl object. TargetInfo responds
+/// to various queries as though it were the primary target, but keeps track of,
+/// and warns about, the first query made of it that are contradictary among the
+/// targets it tracks. For example, if it contains a "PPC32" and "PPC64"
+/// target, it will warn the first time the size of the 'long' datatype is
+/// queried.
+///
+/// Note that TargetInfo does not take ownership of the various targets or the
+/// diagnostic info, but does expect them to be alive for as long as it is.
+///
+class TargetInfo {
+ /// Primary - This tracks the primary target in the target set.
+ ///
+ const TargetInfoImpl *PrimaryTarget;
+
+ /// SecondaryTargets - This tracks the set of secondary targets.
+ ///
+ std::vector<const TargetInfoImpl*> SecondaryTargets;
+
+ /// Diag - If non-null, this object is used to report the first use of
+ /// non-portable functionality in the translation unit.
+ ///
+ Diagnostic *Diag;
+
+ /// NonPortable - This instance variable keeps track of whether or not the
+ /// current translation unit is portable across the set of targets tracked.
+ bool NonPortable;
+
+ /// These are all caches for target values.
+ unsigned WCharWidth;
+
+public:
+ TargetInfo(const TargetInfoImpl *Primary, Diagnostic *D = 0) {
+ PrimaryTarget = Primary;
+ Diag = D;
+ NonPortable = false;
+
+ // Initialize Cache values to uncomputed.
+ WCharWidth = 0;
+ }
+
+ /// isNonPortable - Return true if the current translation unit has used a
+ /// target property that is non-portable across the secondary targets.
+ bool isNonPortable() const {
+ return NonPortable;
+ }
+
+ /// isPortable - Return true if this translation unit is portable across the
+ /// secondary targets so far.
+ bool isPortable() const {
+ return !NonPortable;
+ }
+
+ /// AddSecondaryTarget - Add a secondary target to the target set.
+ void AddSecondaryTarget(const TargetInfoImpl *Secondary) {
+ SecondaryTargets.push_back(Secondary);
+ }
+
+ ///===---- Target property query methods --------------------------------===//
+
+ /// DiagnoseNonPortability - Emit a diagnostic indicating that the current
+ /// translation unit is non-portable due to a construct at the specified
+ /// location. DiagKind indicates what went wrong.
+ void DiagnoseNonPortability(SourceLocation Loc, unsigned DiagKind);
+
+ /// getTargetDefines - Appends the target-specific #define values for this
+ /// target set to the specified buffer.
+ void getTargetDefines(std::vector<char> &DefineBuffer);
+
+ /// isCharSigned - Return true if 'char' is 'signed char' or false if it is
+ /// treated as 'unsigned char'. This is implementation defined according to
+ /// C99 6.2.5p15. In our implementation, this is target-specific.
+ bool isCharSigned(SourceLocation Loc) {
+ // FIXME: implement correctly.
+ return true;
+ }
+
+ /// getPointerWidth - Return the width of pointers on this target, we
+ /// currently assume one pointer type.
+ unsigned getPointerWidth(SourceLocation Loc) {
+ return 32; // FIXME: implement correctly.
+ }
+
+ /// getBoolWidth - Return the size of '_Bool' and C++ 'bool' for this target,
+ /// in bits.
+ unsigned getBoolWidth(SourceLocation Loc) {
+ return 8; // FIXME: implement correctly: wrong for ppc32.
+ }
+
+ /// getCharWidth - Return the size of 'char', 'signed char' and
+ /// 'unsigned char' for this target, in bits.
+ unsigned getCharWidth(SourceLocation Loc) {
+ return 8; // FIXME: implement correctly.
+ }
+
+ /// getShortWidth - Return the size of 'signed short' and 'unsigned short' for
+ /// this target, in bits.
+ unsigned getShortWidth(SourceLocation Loc) {
+ return 16; // FIXME: implement correctly.
+ }
+
+ /// getIntWidth - Return the size of 'signed int' and 'unsigned int' for this
+ /// target, in bits.
+ unsigned getIntWidth(SourceLocation Loc) {
+ return 32; // FIXME: implement correctly.
+ }
+
+ /// getLongWidth - Return the size of 'signed long' and 'unsigned long' for
+ /// this target, in bits.
+ unsigned getLongWidth(SourceLocation Loc) {
+ return 32; // FIXME: implement correctly: wrong for ppc64/x86-64
+ }
+
+ /// getLongLongWidth - Return the size of 'signed long long' and
+ /// 'unsigned long long' for this target, in bits.
+ unsigned getLongLongWidth(SourceLocation Loc) {
+ return 64; // FIXME: implement correctly.
+ }
+
+ /// getWCharWidth - Return the size of wchar_t in bits.
+ ///
+ unsigned getWCharWidth(SourceLocation Loc) {
+ if (!WCharWidth) ComputeWCharWidth(Loc);
+ return WCharWidth;
+ }
+
+ /// getIntMaxTWidth - Return the size of intmax_t and uintmax_t for this
+ /// target, in bits.
+ unsigned getIntMaxTWidth(SourceLocation Loc) {
+ // FIXME: implement correctly.
+ return 64;
+ }
+
+ /// getTargetBuiltins - Return information about target-specific builtins for
+ /// the current primary target, and info about which builtins are non-portable
+ /// across the current set of primary and secondary targets.
+ void getTargetBuiltins(const Builtin::Info *&Records, unsigned &NumRecords,
+ std::vector<const char *> &NonPortableBuiltins) const;
+
+private:
+ void ComputeWCharWidth(SourceLocation Loc);
+};
+
+
+
+
+/// TargetInfoImpl - This class is implemented for specific targets and is used
+/// by the TargetInfo class. Target implementations should initialize instance
+/// variables and implement various virtual methods if the default values are
+/// not appropriate for the target.
+class TargetInfoImpl {
+protected:
+ unsigned WCharWidth; /// sizeof(wchar_t) in bits. Default value is 32.
+public:
+ TargetInfoImpl() : WCharWidth(32) {}
+ virtual ~TargetInfoImpl() {}
+
+ /// getTargetDefines - Return a list of the target-specific #define values set
+ /// when compiling to this target. Each string should be of the form "X",
+ /// which results in '#define X 1' or "X=Y" which results in "#define X Y"
+ virtual void getTargetDefines(std::vector<std::string> &Defines) const = 0;
+
+ /// getWCharWidth - Return the size of wchar_t in bits.
+ ///
+ unsigned getWCharWidth() const { return WCharWidth; }
+
+ /// getTargetBuiltins - Return information about target-specific builtins for
+ /// the target.
+ virtual void getTargetBuiltins(const Builtin::Info *&Records,
+ unsigned &NumRecords) const {
+ Records = 0;
+ NumRecords = 0;
+ }
+private:
+ virtual void ANCHOR(); // out-of-line virtual method for class.
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
new file mode 100644
index 0000000..4fab08d
--- /dev/null
+++ b/include/clang/Basic/TokenKinds.def
@@ -0,0 +1,354 @@
+//===--- TokenKinds.def - C Family Token Kind Database ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the TokenKind database. This includes normal tokens like
+// tok::ampamp (corresponding to the && token) as well as keywords for various
+// languages. Users of this file must optionally #define the TOK, KEYWORD,
+// ALIAS, or PPKEYWORD macros to make use of this file.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TOK
+#define TOK(X)
+#endif
+#ifndef KEYWORD
+#define KEYWORD(X,Y) TOK(kw_ ## X)
+#endif
+#ifndef ALIAS
+#define ALIAS(X,Y)
+#endif
+#ifndef PPKEYWORD
+#define PPKEYWORD(X)
+#endif
+#ifndef CXX_KEYWORD_OPERATOR
+#define CXX_KEYWORD_OPERATOR(X,Y)
+#endif
+#ifndef OBJC1_AT_KEYWORD
+#define OBJC1_AT_KEYWORD(X)
+#endif
+#ifndef OBJC2_AT_KEYWORD
+#define OBJC2_AT_KEYWORD(X)
+#endif
+
+//===----------------------------------------------------------------------===//
+// Preprocessor keywords.
+//===----------------------------------------------------------------------===//
+
+// These have meaning after a '#' at the start of a line. These define enums in
+// the tok::pp_* namespace.
+PPKEYWORD(not_keyword)
+
+// C99 6.10.1 - Conditional Inclusion.
+PPKEYWORD(if)
+PPKEYWORD(ifdef)
+PPKEYWORD(ifndef)
+PPKEYWORD(elif)
+PPKEYWORD(else)
+PPKEYWORD(endif)
+PPKEYWORD(defined)
+
+// C99 6.10.2 - Source File Inclusion.
+PPKEYWORD(include)
+
+// C99 6.10.3 - Macro Replacement.
+PPKEYWORD(define)
+PPKEYWORD(undef)
+
+// C99 6.10.4 - Line Control.
+PPKEYWORD(line)
+
+// C99 6.10.5 - Error Directive.
+PPKEYWORD(error)
+
+// C99 6.10.6 - Pragma Directive.
+PPKEYWORD(pragma)
+
+// GNU Extensions.
+PPKEYWORD(import)
+PPKEYWORD(include_next)
+PPKEYWORD(warning)
+PPKEYWORD(ident)
+PPKEYWORD(sccs)
+PPKEYWORD(assert)
+PPKEYWORD(unassert)
+
+// clang extensions.
+PPKEYWORD(define_target)
+PPKEYWORD(define_other_target)
+
+
+//===----------------------------------------------------------------------===//
+// Language keywords.
+//===----------------------------------------------------------------------===//
+
+// These define members of the tok::kw_* namespace.
+
+TOK(unknown) // Not a token.
+TOK(eof) // End of file.
+TOK(eom) // End of macro (end of line inside a macro).
+
+// C99 6.4.9: Comments.
+TOK(comment) // Comment (only in -E -C[C] mode)
+
+// C99 6.4.2: Identifiers.
+TOK(identifier) // abcde123
+
+// C99 6.4.4.1: Integer Constants
+// C99 6.4.4.2: Floating Constants
+TOK(numeric_constant) // 0x123
+
+// C99 6.4.4: Character Constants
+TOK(char_constant) // 'a' L'b'
+
+// C99 6.4.5: String Literals.
+TOK(string_literal) // "foo"
+TOK(wide_string_literal) // L"foo"
+TOK(angle_string_literal)// <foo>
+
+// C99 6.4.6: Punctuators.
+TOK(l_square) // [
+TOK(r_square) // ]
+TOK(l_paren) // (
+TOK(r_paren) // )
+TOK(l_brace) // {
+TOK(r_brace) // }
+TOK(period) // .
+TOK(ellipsis) // ...
+TOK(amp) // &
+TOK(ampamp) // &&
+TOK(ampequal) // &=
+TOK(star) // *
+TOK(starequal) // *=
+TOK(plus) // +
+TOK(plusplus) // ++
+TOK(plusequal) // +=
+TOK(minus) // -
+TOK(arrow) // ->
+TOK(minusminus) // --
+TOK(minusequal) // -=
+TOK(tilde) // ~
+TOK(exclaim) // !
+TOK(exclaimequal) // !=
+TOK(slash) // /
+TOK(slashequal) // /=
+TOK(percent) // %
+TOK(percentequal) // %=
+TOK(less) // <
+TOK(lessless) // <<
+TOK(lessequal) // <=
+TOK(lesslessequal) // <<=
+TOK(greater) // >
+TOK(greatergreater) // >>
+TOK(greaterequal) // >=
+TOK(greatergreaterequal) // >>=
+TOK(caret) // ^
+TOK(caretequal) // ^=
+TOK(pipe) // |
+TOK(pipepipe) // ||
+TOK(pipeequal) // |=
+TOK(question) // ?
+TOK(colon) // :
+TOK(semi) // ;
+TOK(equal) // =
+TOK(equalequal) // ==
+TOK(comma) // ,
+TOK(hash) // #
+TOK(hashhash) // ##
+TOK(hashat) // #@
+
+// C++ Support
+TOK(periodstar) // .*
+TOK(arrowstar) // ->*
+TOK(coloncolon) // ::
+
+// Objective C support.
+TOK(at) // @
+
+// at_identifier // @foo
+// at_string // @"foo"
+
+
+// C99 6.4.1: Keywords. These turn into kw_* tokens.
+// Flags allowed:
+// NOTC90 - In C90, this token is never available.
+// EXTC90 - In C90, this token is an extension that is enabled unless strict.
+// NOTC99 - In C99, this token is never available.
+// EXTC99 - In C99, this token is an extension that is enabled unless strict.
+// NOTCPP - In C++, this token is never available.
+// EXTCPP - In C++, this token is an extension that is enabled unless strict.
+//
+KEYWORD(auto , 0)
+KEYWORD(break , 0)
+KEYWORD(case , 0)
+KEYWORD(char , 0)
+KEYWORD(const , 0)
+KEYWORD(continue , 0)
+KEYWORD(default , 0)
+KEYWORD(do , 0)
+KEYWORD(double , 0)
+KEYWORD(else , 0)
+KEYWORD(enum , 0)
+KEYWORD(extern , 0)
+KEYWORD(float , 0)
+KEYWORD(for , 0)
+KEYWORD(goto , 0)
+KEYWORD(if , 0)
+KEYWORD(inline , EXTC90) // Ext in C90, ok in C99/C++
+KEYWORD(int , 0)
+KEYWORD(long , 0)
+KEYWORD(register , 0)
+KEYWORD(restrict , EXTC90) // Ext in C90
+KEYWORD(return , 0)
+KEYWORD(short , 0)
+KEYWORD(signed , 0)
+KEYWORD(sizeof , 0)
+KEYWORD(static , 0)
+KEYWORD(struct , 0)
+KEYWORD(switch , 0)
+KEYWORD(typedef , 0)
+KEYWORD(union , 0)
+KEYWORD(unsigned , 0)
+KEYWORD(void , 0)
+KEYWORD(volatile , 0)
+KEYWORD(while , 0)
+KEYWORD(_Bool , EXTC90|EXTCPP) // C99 only
+KEYWORD(_Complex , EXTC90) // C99/C++
+KEYWORD(_Imaginary , EXTC90|NOTCPP) // C90 only
+
+// Special tokens to the compiler.
+KEYWORD(__func__ , EXTC90|EXTCPP) // Only in C99.
+KEYWORD(__FUNCTION__ , EXTC90|EXTC99|EXTCPP) // GCC Extension.
+KEYWORD(__PRETTY_FUNCTION__ , EXTC90|EXTC99|EXTCPP) // GCC Extension.
+
+// C++ 2.11p1: Keywords.
+KEYWORD(asm , EXTC90|EXTC99) // Exts in C90/C99
+KEYWORD(bool , NOTC90|NOTC99)
+KEYWORD(catch , NOTC90|NOTC99)
+KEYWORD(class , NOTC90|NOTC99)
+KEYWORD(const_cast , NOTC90|NOTC99)
+KEYWORD(delete , NOTC90|NOTC99)
+KEYWORD(dynamic_cast , NOTC90|NOTC99)
+KEYWORD(explicit , NOTC90|NOTC99)
+KEYWORD(export , NOTC90|NOTC99)
+KEYWORD(false , NOTC90|NOTC99)
+KEYWORD(friend , NOTC90|NOTC99)
+KEYWORD(mutable , NOTC90|NOTC99)
+KEYWORD(namespace , NOTC90|NOTC99)
+KEYWORD(new , NOTC90|NOTC99)
+KEYWORD(operator , NOTC90|NOTC99)
+KEYWORD(private , NOTC90|NOTC99)
+KEYWORD(protected , NOTC90|NOTC99)
+KEYWORD(public , NOTC90|NOTC99)
+KEYWORD(reinterpret_cast , NOTC90|NOTC99)
+KEYWORD(static_cast , NOTC90|NOTC99)
+KEYWORD(template , NOTC90|NOTC99)
+KEYWORD(this , NOTC90|NOTC99)
+KEYWORD(throw , NOTC90|NOTC99)
+KEYWORD(true , NOTC90|NOTC99)
+KEYWORD(try , NOTC90|NOTC99)
+KEYWORD(typename , NOTC90|NOTC99)
+KEYWORD(typeid , NOTC90|NOTC99)
+KEYWORD(using , NOTC90|NOTC99)
+KEYWORD(virtual , NOTC90|NOTC99)
+KEYWORD(wchar_t , NOTC90|NOTC99)
+
+// C++ 2.5p2: Alternative Representations.
+CXX_KEYWORD_OPERATOR(and , ampamp)
+CXX_KEYWORD_OPERATOR(and_eq , ampequal)
+CXX_KEYWORD_OPERATOR(bitand , amp)
+CXX_KEYWORD_OPERATOR(bitor , pipe)
+CXX_KEYWORD_OPERATOR(compl , tilde)
+CXX_KEYWORD_OPERATOR(not , exclaim)
+CXX_KEYWORD_OPERATOR(not_eq , exclaimequal)
+CXX_KEYWORD_OPERATOR(or , pipepipe)
+CXX_KEYWORD_OPERATOR(or_eq , pipeequal)
+CXX_KEYWORD_OPERATOR(xor , caret)
+CXX_KEYWORD_OPERATOR(xor_eq , caretequal)
+
+// GNU Extensions.
+KEYWORD(_Decimal32 , EXTC90|EXTC99|EXTCPP)
+KEYWORD(_Decimal64 , EXTC90|EXTC99|EXTCPP)
+KEYWORD(_Decimal128 , EXTC90|EXTC99|EXTCPP)
+KEYWORD(typeof , EXTC90|EXTC99|EXTCPP)
+KEYWORD(__null , NOTC90|NOTC99|EXTCPP) // C++-only Extensn
+KEYWORD(__alignof , EXTC90|EXTC99|EXTCPP)
+KEYWORD(__attribute , EXTC90|EXTC99|EXTCPP)
+KEYWORD(__builtin_choose_expr , EXTC90|EXTC99|EXTCPP)
+KEYWORD(__builtin_offsetof , EXTC90|EXTC99|EXTCPP)
+KEYWORD(__builtin_types_compatible_p, EXTC90|EXTC99|EXTCPP)
+KEYWORD(__builtin_va_arg , EXTC90|EXTC99|EXTCPP)
+KEYWORD(__extension__ , 0) // Not treated as an extension!
+KEYWORD(__imag , EXTC90|EXTC99|EXTCPP)
+KEYWORD(__label__ , EXTC90|EXTC99|EXTCPP)
+KEYWORD(__real , EXTC90|EXTC99|EXTCPP)
+KEYWORD(__thread , EXTC90|EXTC99|EXTCPP)
+
+// Alternate spelling for various tokens. There are GCC extensions in all
+// languages, but should not be disabled in strict conformance mode.
+ALIAS("__attribute__", __attribute)
+ALIAS("__const" , const )
+ALIAS("__const__" , const )
+ALIAS("__alignof__" , __alignof )
+ALIAS("__asm" , asm )
+ALIAS("__asm__" , asm )
+ALIAS("__complex" , _Complex )
+ALIAS("__complex__" , _Complex )
+ALIAS("__imag__" , __imag )
+ALIAS("__inline" , inline )
+ALIAS("__inline__" , inline )
+ALIAS("__real__" , __real )
+ALIAS("__restrict" , restrict )
+ALIAS("__restrict__" , restrict )
+ALIAS("__signed" , signed )
+ALIAS("__signed__" , signed )
+ALIAS("__typeof" , typeof )
+ALIAS("__typeof__" , typeof )
+ALIAS("__volatile" , volatile )
+ALIAS("__volatile__" , volatile )
+
+
+//===----------------------------------------------------------------------===//
+// Objective-C @-preceeded keywords.
+//===----------------------------------------------------------------------===//
+
+// These have meaning after an '@' in Objective-C mode. These define enums in
+// the tok::objc_* namespace.
+
+OBJC1_AT_KEYWORD(not_keyword)
+OBJC1_AT_KEYWORD(class)
+OBJC1_AT_KEYWORD(compatibility_alias)
+OBJC1_AT_KEYWORD(defs)
+OBJC1_AT_KEYWORD(encode)
+OBJC1_AT_KEYWORD(end)
+OBJC1_AT_KEYWORD(implementation)
+OBJC1_AT_KEYWORD(interface)
+OBJC1_AT_KEYWORD(private)
+OBJC1_AT_KEYWORD(protected)
+OBJC1_AT_KEYWORD(protocol)
+OBJC1_AT_KEYWORD(public)
+OBJC1_AT_KEYWORD(selector)
+OBJC1_AT_KEYWORD(throw)
+OBJC1_AT_KEYWORD(try)
+OBJC1_AT_KEYWORD(catch)
+OBJC1_AT_KEYWORD(finally)
+OBJC1_AT_KEYWORD(synchronized)
+
+// I'm guessing this is an objc2 keyword, what are the others?
+OBJC2_AT_KEYWORD(property)
+
+// TODO: What to do about context-sensitive keywords like:
+// bycopy/byref/in/inout/oneway/out?
+
+#undef OBJC2_AT_KEYWORD
+#undef OBJC1_AT_KEYWORD
+#undef CXX_KEYWORD_OPERATOR
+#undef PPKEYWORD
+#undef ALIAS
+#undef KEYWORD
+#undef TOK
diff --git a/include/clang/Basic/TokenKinds.h b/include/clang/Basic/TokenKinds.h
new file mode 100644
index 0000000..e51f0c7
--- /dev/null
+++ b/include/clang/Basic/TokenKinds.h
@@ -0,0 +1,51 @@
+//===--- TokenKinds.h - Enum values for C Token Kinds -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the TokenKind enum and support functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOKENKINDS_H
+#define LLVM_CLANG_TOKENKINDS_H
+
+namespace clang {
+
+namespace tok {
+
+/// TokenKind - This provides a simple uniform namespace for tokens from all C
+/// languages.
+enum TokenKind {
+#define TOK(X) X,
+#include "clang/Basic/TokenKinds.def"
+ NUM_TOKENS
+};
+
+/// PPKeywordKind - This provides a namespace for preprocessor keywords which
+/// start with a '#' at the beginning of the line.
+enum PPKeywordKind {
+#define PPKEYWORD(X) pp_##X,
+#include "clang/Basic/TokenKinds.def"
+ NUM_PP_KEYWORDS
+};
+
+/// ObjCKeywordKind - This provides a namespace for Objective-C keywords which
+/// start with an '@'.
+enum ObjCKeywordKind {
+#define OBJC1_AT_KEYWORD(X) objc_##X,
+#define OBJC2_AT_KEYWORD(X) objc_##X,
+#include "clang/Basic/TokenKinds.def"
+ NUM_OBJC_KEYWORDS
+};
+
+const char *getTokenName(enum TokenKind Kind);
+
+} // end namespace tok
+} // end namespace clang
+
+#endif
diff --git a/include/clang/CodeGen/ModuleBuilder.h b/include/clang/CodeGen/ModuleBuilder.h
new file mode 100644
index 0000000..e9cb2b5
--- /dev/null
+++ b/include/clang/CodeGen/ModuleBuilder.h
@@ -0,0 +1,47 @@
+//===--- CodeGen/ModuleBuilder.h - Build LLVM from ASTs ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ModuleBuilder interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CODEGEN_MODULEBUILDER_H
+#define LLVM_CLANG_CODEGEN_MODULEBUILDER_H
+
+namespace llvm {
+ class Module;
+}
+
+namespace clang {
+ class ASTContext;
+ class FunctionDecl;
+
+namespace CodeGen {
+ /// BuilderTy - This is an opaque type used to reference ModuleBuilder
+ /// objects.
+ typedef void BuilderTy;
+
+ /// Init - Create an ModuleBuilder with the specified ASTContext.
+ BuilderTy *Init(ASTContext &Context, llvm::Module &M);
+
+ /// CodeGenFunction - Convert the AST node for a FunctionDecl into LLVM.
+ ///
+ void CodeGenFunction(BuilderTy *Builder, FunctionDecl *D);
+
+ /// PrintStats - Emit statistic information to stderr.
+ ///
+ void PrintStats(BuilderTy *Builder);
+
+ /// Terminate - Gracefully shut down the builder.
+ ///
+ void Terminate(BuilderTy *Builder);
+} // end namespace CodeGen
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/DirectoryLookup.h b/include/clang/Lex/DirectoryLookup.h
new file mode 100644
index 0000000..a1cfb0a
--- /dev/null
+++ b/include/clang/Lex/DirectoryLookup.h
@@ -0,0 +1,70 @@
+//===--- DirectoryLookup.h - Info for searching for headers -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the DirectoryLookup interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LEX_DIRECTORYLOOKUP_H
+#define LLVM_CLANG_LEX_DIRECTORYLOOKUP_H
+
+namespace clang {
+class DirectoryEntry;
+
+/// DirectoryLookup - This class is used to specify the search order for
+/// directories in #include directives.
+class DirectoryLookup {
+public:
+ enum DirType {
+ NormalHeaderDir,
+ SystemHeaderDir,
+ ExternCSystemHeaderDir
+ };
+private:
+ /// Dir - This is the actual directory that we're referring to.
+ ///
+ const DirectoryEntry *Dir;
+
+ /// DirCharacteristic - The type of directory this is, one of the DirType enum
+ /// values.
+ DirType DirCharacteristic : 2;
+
+ /// UserSupplied - True if this is a user-supplied directory.
+ ///
+ bool UserSupplied : 1;
+
+ /// Framework - True if this is a framework directory search-path.
+ ///
+ bool Framework : 1;
+public:
+ DirectoryLookup(const DirectoryEntry *dir, DirType DT, bool isUser,
+ bool isFramework)
+ : Dir(dir), DirCharacteristic(DT), UserSupplied(isUser),
+ Framework(isFramework) {}
+
+ /// getDir - Return the directory that this entry refers to.
+ ///
+ const DirectoryEntry *getDir() const { return Dir; }
+
+ /// DirCharacteristic - The type of directory this is, one of the DirType enum
+ /// values.
+ DirType getDirCharacteristic() const { return DirCharacteristic; }
+
+ /// isUserSupplied - True if this is a user-supplied directory.
+ ///
+ bool isUserSupplied() const { return UserSupplied; }
+
+ /// isFramework - True if this is a framework directory.
+ ///
+ bool isFramework() const { return Framework; }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h
new file mode 100644
index 0000000..79b3366
--- /dev/null
+++ b/include/clang/Lex/HeaderSearch.h
@@ -0,0 +1,166 @@
+//===--- HeaderSearch.h - Resolve Header File Locations ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the HeaderSearch interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LEX_HEADERSEARCH_H
+#define LLVM_CLANG_LEX_HEADERSEARCH_H
+
+#include "clang/Lex/DirectoryLookup.h"
+#include "llvm/ADT/StringMap.h"
+#include <vector>
+
+namespace clang {
+class FileEntry;
+class FileManager;
+class IdentifierInfo;
+
+
+/// HeaderSearch - This class encapsulates the information needed to find the
+/// file referenced by a #include or #include_next, (sub-)framework lookup, etc.
+class HeaderSearch {
+ FileManager &FileMgr;
+
+ /// #include search path information. Requests for #include "x" search the
+ /// directory of the #including file first, then each directory in SearchDirs
+ /// consequtively. Requests for <x> search the current dir first, then each
+ /// directory in SearchDirs, starting at SystemDirIdx, consequtively. If
+ /// NoCurDirSearch is true, then the check for the file in the current
+ /// directory is supressed.
+ std::vector<DirectoryLookup> SearchDirs;
+ unsigned SystemDirIdx;
+ bool NoCurDirSearch;
+
+ /// PreFileInfo - The preprocessor keeps track of this information for each
+ /// file that is #included.
+ struct PerFileInfo {
+ /// isImport - True if this is a #import'd or #pragma once file.
+ bool isImport : 1;
+
+ /// DirInfo - Keep track of whether this is a system header, and if so,
+ /// whether it is C++ clean or not. This can be set by the include paths or
+ /// by #pragma gcc system_header.
+ DirectoryLookup::DirType DirInfo : 2;
+
+ /// NumIncludes - This is the number of times the file has been included
+ /// already.
+ unsigned short NumIncludes;
+
+ /// ControllingMacro - If this file has a #ifndef XXX (or equivalent) guard
+ /// that protects the entire contents of the file, this is the identifier
+ /// for the macro that controls whether or not it has any effect.
+ const IdentifierInfo *ControllingMacro;
+
+ PerFileInfo() : isImport(false), DirInfo(DirectoryLookup::NormalHeaderDir),
+ NumIncludes(0), ControllingMacro(0) {}
+ };
+
+ /// FileInfo - This contains all of the preprocessor-specific data about files
+ /// that are included. The vector is indexed by the FileEntry's UID.
+ ///
+ std::vector<PerFileInfo> FileInfo;
+
+ /// FrameworkMap - This is a collection mapping a framework or subframework
+ /// name like "Carbon" to the Carbon.framework directory.
+ llvm::StringMap<const DirectoryEntry *> FrameworkMap;
+
+ // Various statistics we track for performance analysis.
+ unsigned NumIncluded;
+ unsigned NumMultiIncludeFileOptzn;
+ unsigned NumFrameworkLookups, NumSubFrameworkLookups;
+public:
+ HeaderSearch(FileManager &FM);
+
+ FileManager &getFileMgr() const { return FileMgr; }
+
+ /// SetSearchPaths - Interface for setting the file search paths.
+ ///
+ void SetSearchPaths(const std::vector<DirectoryLookup> &dirs,
+ unsigned systemDirIdx, bool noCurDirSearch) {
+ SearchDirs = dirs;
+ SystemDirIdx = systemDirIdx;
+ NoCurDirSearch = noCurDirSearch;
+ }
+
+ /// ClearFileInfo - Forget everything we know about headers so far.
+ void ClearFileInfo() {
+ FileInfo.clear();
+ }
+
+ /// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
+ /// return null on failure. isAngled indicates whether the file reference is
+ /// a <> reference. If successful, this returns 'UsedDir', the
+ /// DirectoryLookup member the file was found in, or null if not applicable.
+ /// If CurDir is non-null, the file was found in the specified directory
+ /// search location. This is used to implement #include_next. CurFileEnt, if
+ /// non-null, indicates where the #including file is, in case a relative
+ /// search is needed.
+ const FileEntry *LookupFile(const char *FilenameStart,
+ const char *FilenameEnd, bool isAngled,
+ const DirectoryLookup *FromDir,
+ const DirectoryLookup *&CurDir,
+ const FileEntry *CurFileEnt);
+
+ /// LookupSubframeworkHeader - Look up a subframework for the specified
+ /// #include file. For example, if #include'ing <HIToolbox/HIToolbox.h> from
+ /// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox
+ /// is a subframework within Carbon.framework. If so, return the FileEntry
+ /// for the designated file, otherwise return null.
+ const FileEntry *LookupSubframeworkHeader(const char *FilenameStart,
+ const char *FilenameEnd,
+ const FileEntry *RelativeFileEnt);
+
+ /// ShouldEnterIncludeFile - Mark the specified file as a target of of a
+ /// #include, #include_next, or #import directive. Return false if #including
+ /// the file will have no effect or true if we should include it.
+ bool ShouldEnterIncludeFile(const FileEntry *File, bool isImport);
+
+
+ /// getFileDirFlavor - Return whether the specified file is a normal header,
+ /// a system header, or a C++ friendly system header.
+ DirectoryLookup::DirType getFileDirFlavor(const FileEntry *File) {
+ return getFileInfo(File).DirInfo;
+ }
+
+ /// MarkFileIncludeOnce - Mark the specified file as a "once only" file, e.g.
+ /// due to #pragma once.
+ void MarkFileIncludeOnce(const FileEntry *File) {
+ getFileInfo(File).isImport = true;
+ }
+
+ /// MarkFileSystemHeader - Mark the specified fiel as a system header, e.g.
+ /// due to #pragma GCC system_header.
+ void MarkFileSystemHeader(const FileEntry *File) {
+ getFileInfo(File).DirInfo = DirectoryLookup::SystemHeaderDir;
+ }
+
+ /// SetFileControllingMacro - Mark the specified file as having a controlling
+ /// macro. This is used by the multiple-include optimization to eliminate
+ /// no-op #includes.
+ void SetFileControllingMacro(const FileEntry *File,
+ const IdentifierInfo *ControllingMacro) {
+ getFileInfo(File).ControllingMacro = ControllingMacro;
+ }
+
+ void PrintStats();
+private:
+ const FileEntry *DoFrameworkLookup(const DirectoryEntry *Dir,
+ const char *FilenameStart,
+ const char *FilenameEnd);
+
+ /// getFileInfo - Return the PerFileInfo structure for the specified
+ /// FileEntry.
+ PerFileInfo &getFileInfo(const FileEntry *FE);
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/IdentifierTable.h b/include/clang/Lex/IdentifierTable.h
new file mode 100644
index 0000000..4edba60
--- /dev/null
+++ b/include/clang/Lex/IdentifierTable.h
@@ -0,0 +1,171 @@
+//===--- IdentifierTable.h - Hash table for identifier lookup ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the IdentifierInfo and IdentifierTable interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LEX_IDENTIFIERTABLE_H
+#define LLVM_CLANG_LEX_IDENTIFIERTABLE_H
+
+#include "clang/Basic/TokenKinds.h"
+#include "llvm/ADT/StringMap.h"
+#include <string>
+
+namespace clang {
+ class MacroInfo;
+ class LangOptions;
+
+/// IdentifierInfo - One of these records is kept for each identifier that
+/// is lexed. This contains information about whether the token was #define'd,
+/// is a language keyword, or if it is a front-end token of some sort (e.g. a
+/// variable or function name). The preprocessor keeps this information in a
+/// set, and all tok::identifier tokens have a pointer to one of these.
+class IdentifierInfo {
+ MacroInfo *Macro; // Set if this identifier is #define'd.
+ tok::TokenKind TokenID : 8; // Front-end token ID or tok::identifier.
+ tok::PPKeywordKind PPID : 5; // ID for preprocessor command like #'ifdef'.
+ tok::ObjCKeywordKind ObjCID : 5; // ID for objc @ keyword like @'protocol'.
+ unsigned BuiltinID :12; // ID if this is a builtin (__builtin_inf).
+ bool IsExtension : 1; // True if identifier is a lang extension.
+ bool IsPoisoned : 1; // True if identifier is poisoned.
+ bool IsOtherTargetMacro : 1; // True if ident is macro on another target.
+ bool IsCPPOperatorKeyword : 1; // True if ident is a C++ operator keyword.
+ bool IsNonPortableBuiltin : 1; // True if builtin varies across targets.
+ void *FETokenInfo; // Managed by the language front-end.
+ IdentifierInfo(const IdentifierInfo&); // NONCOPYABLE.
+public:
+ IdentifierInfo();
+ ~IdentifierInfo();
+
+ /// getName - Return the actual string for this identifier. The length of
+ /// this string is stored in NameLen, and the returned string is properly null
+ /// terminated.
+ ///
+ const char *getName() const {
+ // String data is stored immediately after the IdentifierInfo object.
+ return (const char*)(this+1);
+ }
+
+ /// getMacroInfo - Return macro information about this identifier, or null if
+ /// it is not a macro.
+ MacroInfo *getMacroInfo() const { return Macro; }
+ void setMacroInfo(MacroInfo *I) { Macro = I; }
+
+ /// get/setTokenID - If this is a source-language token (e.g. 'for'), this API
+ /// can be used to cause the lexer to map identifiers to source-language
+ /// tokens.
+ tok::TokenKind getTokenID() const { return TokenID; }
+ void setTokenID(tok::TokenKind ID) { TokenID = ID; }
+
+ /// getPPKeywordID - Return the preprocessor keyword ID for this identifier.
+ /// For example, define will return tok::pp_define.
+ tok::PPKeywordKind getPPKeywordID() const { return PPID; }
+ void setPPKeywordID(tok::PPKeywordKind ID) { PPID = ID; }
+
+ /// getObjCKeywordID - Return the Objective-C keyword ID for the this
+ /// identifier. For example, 'class' will return tok::objc_class if ObjC is
+ /// enabled.
+ tok::ObjCKeywordKind getObjCKeywordID() const { return ObjCID; }
+ void setObjCKeywordID(tok::ObjCKeywordKind ID) { ObjCID = ID; }
+
+ /// getBuiltinID - Return a value indicating whether this is a builtin
+ /// function. 0 is not-built-in. 1 is builtin-for-some-nonprimary-target.
+ /// 2+ are specific builtin functions.
+ unsigned getBuiltinID() const { return BuiltinID; }
+ void setBuiltinID(unsigned ID) {
+ assert(ID < (1 << 12) && "ID too large for field!");
+ BuiltinID = ID;
+ }
+
+ /// isNonPortableBuiltin - Return true if this identifier corresponds to a
+ /// builtin on some other target, but isn't one on this target, or if it is on
+ /// the target but not on another, or if it is on both but it differs somehow
+ /// in behavior.
+ bool isNonPortableBuiltin() const { return IsNonPortableBuiltin; }
+ void setNonPortableBuiltin(bool Val) { IsNonPortableBuiltin = Val; }
+
+ /// get/setExtension - Initialize information about whether or not this
+ /// language token is an extension. This controls extension warnings, and is
+ /// only valid if a custom token ID is set.
+ bool isExtensionToken() const { return IsExtension; }
+ void setIsExtensionToken(bool Val) { IsExtension = Val; }
+
+ /// setIsPoisoned - Mark this identifier as poisoned. After poisoning, the
+ /// Preprocessor will emit an error every time this token is used.
+ void setIsPoisoned(bool Value = true) { IsPoisoned = Value; }
+
+ /// isPoisoned - Return true if this token has been poisoned.
+ bool isPoisoned() const { return IsPoisoned; }
+
+ /// setIsOtherTargetMacro/isOtherTargetMacro control whether this identifier
+ /// is seen as being a macro on some other target.
+ void setIsOtherTargetMacro(bool Val = true) { IsOtherTargetMacro = Val; }
+ bool isOtherTargetMacro() const { return IsOtherTargetMacro; }
+
+ /// isCPlusPlusOperatorKeyword/setIsCPlusPlusOperatorKeyword controls whether
+ /// this identifier is a C++ alternate representation of an operator.
+ void setIsCPlusplusOperatorKeyword(bool Val = true)
+ { IsCPPOperatorKeyword = Val; }
+ bool isCPlusPlusOperatorKeyword() const { return IsCPPOperatorKeyword; }
+
+ /// getFETokenInfo/setFETokenInfo - The language front-end is allowed to
+ /// associate arbitrary metadata with this token.
+ template<typename T>
+ T *getFETokenInfo() const { return static_cast<T*>(FETokenInfo); }
+ void setFETokenInfo(void *T) { FETokenInfo = T; }
+};
+
+
+
+/// IdentifierTable - This table implements an efficient mapping from strings to
+/// IdentifierInfo nodes. It has no other purpose, but this is an
+/// extremely performance-critical piece of the code, as each occurrance of
+/// every identifier goes through here when lexed.
+class IdentifierTable {
+ // Shark shows that using MallocAllocator is *much* slower than using this
+ // BumpPtrAllocator!
+ typedef llvm::StringMap<IdentifierInfo, llvm::BumpPtrAllocator> HashTableTy;
+ HashTableTy HashTable;
+public:
+ /// IdentifierTable ctor - Create the identifier table, populating it with
+ /// info about the language keywords for the language specified by LangOpts.
+ IdentifierTable(const LangOptions &LangOpts);
+
+ /// get - Return the identifier token info for the specified named identifier.
+ ///
+ IdentifierInfo &get(const char *NameStart, const char *NameEnd) {
+ return HashTable.GetOrCreateValue(NameStart, NameEnd).getValue();
+ }
+
+ IdentifierInfo &get(const char *Name) {
+ return get(Name, Name+strlen(Name));
+ }
+ IdentifierInfo &get(const std::string &Name) {
+ // Don't use c_str() here: no need to be null terminated.
+ const char *NameBytes = &Name[0];
+ return get(NameBytes, NameBytes+Name.size());
+ }
+
+ typedef HashTableTy::const_iterator iterator;
+ typedef HashTableTy::const_iterator const_iterator;
+
+ iterator begin() const { return HashTable.begin(); }
+ iterator end() const { return HashTable.end(); }
+
+ /// PrintStats - Print some statistics to stderr that indicate how well the
+ /// hashing is doing.
+ void PrintStats() const;
+private:
+ void AddKeywords(const LangOptions &LangOpts);
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h
new file mode 100644
index 0000000..db0c718
--- /dev/null
+++ b/include/clang/Lex/Lexer.h
@@ -0,0 +1,353 @@
+//===--- Lexer.h - C Language Family Lexer ----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the Lexer interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LEXER_H
+#define LLVM_CLANG_LEXER_H
+
+#include "clang/Lex/LexerToken.h"
+#include "clang/Lex/MultipleIncludeOpt.h"
+#include "clang/Basic/LangOptions.h"
+#include <string>
+#include <vector>
+
+namespace llvm {
+ class MemoryBuffer;
+}
+
+namespace clang {
+class Diagnostic;
+class Preprocessor;
+
+/// Lexer - This provides a simple interface that turns a text buffer into a
+/// stream of tokens. This provides no support for file reading or buffering,
+/// or buffering/seeking of tokens, only forward lexing is supported. It relies
+/// on the specified Preprocessor object to handle preprocessor directives, etc.
+class Lexer {
+ //===--------------------------------------------------------------------===//
+ // Constant configuration values for this lexer.
+ const char * const BufferEnd; // End of the buffer.
+ const llvm::MemoryBuffer *InputFile; // The file we are reading from.
+ unsigned CurFileID; // FileID for the current input file.
+ Preprocessor &PP; // Preprocessor object controlling lexing.
+ LangOptions Features; // Features enabled by this language (cache).
+ bool Is_PragmaLexer; // True if lexer for _Pragma handling.
+ bool IsMainFile; // True if top-level file.
+
+ //===--------------------------------------------------------------------===//
+ // Context-specific lexing flags set by the preprocessor.
+ //
+
+ /// ParsingPreprocessorDirective - This is true when parsing #XXX. This turns
+ /// '\n' into a tok::eom token.
+ bool ParsingPreprocessorDirective;
+
+ /// ParsingFilename - True after #include: this turns <xx> into a
+ /// tok::angle_string_literal token.
+ bool ParsingFilename;
+
+ /// LexingRawMode - True if in raw mode: This flag disables interpretation of
+ /// tokens and is a far faster mode to lex in than non-raw-mode. This flag:
+ /// 1. If EOF of the current lexer is found, the include stack isn't popped.
+ /// 2. Identifier information is not looked up for identifier tokens. As an
+ /// effect of this, implicit macro expansion is naturally disabled.
+ /// 3. "#" tokens at the start of a line are treated as normal tokens, not
+ /// implicitly transformed by the lexer.
+ /// 4. All diagnostic messages are disabled, except for unterminated /*.
+ /// 5. The only callback made into the preprocessor is to report a hard error
+ /// on an unterminated '/*' comment.
+ bool LexingRawMode;
+
+ /// KeepCommentMode - The lexer can optionally keep C & BCPL-style comments,
+ /// and return them as tokens. This is used for -C and -CC modes.
+ bool KeepCommentMode;
+
+ //===--------------------------------------------------------------------===//
+ // Context that changes as the file is lexed.
+ // NOTE: any state that mutates when in raw mode must have save/restore code
+ // in Lexer::isNextPPTokenLParen.
+
+ // BufferPtr - Current pointer into the buffer. This is the next character
+ // to be lexed.
+ const char *BufferPtr;
+
+ // IsAtStartOfLine - True if the next lexed token should get the "start of
+ // line" flag set on it.
+ bool IsAtStartOfLine;
+
+ /// MIOpt - This is a state machine that detects the #ifndef-wrapping a file
+ /// idiom for the multiple-include optimization.
+ MultipleIncludeOpt MIOpt;
+
+ /// ConditionalStack - Information about the set of #if/#ifdef/#ifndef blocks
+ /// we are currently in.
+ std::vector<PPConditionalInfo> ConditionalStack;
+
+ friend class Preprocessor;
+public:
+
+ /// Lexer constructor - Create a new lexer object for the specified buffer
+ /// with the specified preprocessor managing the lexing process. This lexer
+ /// assumes that the specified MemoryBuffer and Preprocessor objects will
+ /// outlive it, but doesn't take ownership of either pointer.
+ Lexer(const llvm::MemoryBuffer *InBuffer, unsigned CurFileID,
+ Preprocessor &PP, const char *BufStart = 0, const char *BufEnd = 0);
+
+ /// getFeatures - Return the language features currently enabled. NOTE: this
+ /// lexer modifies features as a file is parsed!
+ const LangOptions &getFeatures() const { return Features; }
+
+ /// getCurFileID - Return the FileID for the file we are lexing out of. This
+ /// implicitly encodes the include path to get to the file.
+ unsigned getCurFileID() const { return CurFileID; }
+
+ /// setIsMainFile - Mark this lexer as being the lexer for the top-level
+ /// source file.
+ void setIsMainFile() {
+ IsMainFile = true;
+ }
+
+ /// isMainFile - Return true if this is the top-level file.
+ ///
+ bool isMainFile() const { return IsMainFile; }
+
+ /// Lex - Return the next token in the file. If this is the end of file, it
+ /// return the tok::eof token. Return true if an error occurred and
+ /// compilation should terminate, false if normal. This implicitly involves
+ /// the preprocessor.
+ void Lex(LexerToken &Result) {
+ // Start a new token.
+ Result.startToken();
+
+ // NOTE, any changes here should also change code after calls to
+ // Preprocessor::HandleDirective
+ if (IsAtStartOfLine) {
+ Result.setFlag(LexerToken::StartOfLine);
+ IsAtStartOfLine = false;
+ }
+
+ // Get a token. Note that this may delete the current lexer if the end of
+ // file is reached.
+ LexTokenInternal(Result);
+ }
+
+ /// LexRawToken - Switch the lexer to raw mode, lex a token into Result and
+ /// switch it back. Return true if the 'next character to read' pointer
+ /// points and the end of the lexer buffer, false otherwise.
+ bool LexRawToken(LexerToken &Result) {
+ assert(!LexingRawMode && "Already in raw mode!");
+ LexingRawMode = true;
+ Lex(Result);
+ LexingRawMode = false;
+ return BufferPtr == BufferEnd;
+ }
+
+ /// ReadToEndOfLine - Read the rest of the current preprocessor line as an
+ /// uninterpreted string. This switches the lexer out of directive mode.
+ std::string ReadToEndOfLine();
+
+
+ /// Diag - Forwarding function for diagnostics. This translate a source
+ /// position in the current buffer into a SourceLocation object for rendering.
+ void Diag(const char *Loc, unsigned DiagID,
+ const std::string &Msg = std::string()) const;
+ void Diag(SourceLocation Loc, unsigned DiagID,
+ const std::string &Msg = std::string()) const;
+
+ /// getSourceLocation - Return a source location identifier for the specified
+ /// offset in the current file.
+ SourceLocation getSourceLocation(const char *Loc) const;
+
+ /// Stringify - Convert the specified string into a C string by escaping '\'
+ /// and " characters. This does not add surrounding ""'s to the string.
+ /// If Charify is true, this escapes the ' character instead of ".
+ static std::string Stringify(const std::string &Str, bool Charify = false);
+
+ //===--------------------------------------------------------------------===//
+ // Internal implementation interfaces.
+private:
+
+ /// LexTokenInternal - Internal interface to lex a preprocessing token. Called
+ /// by Lex.
+ ///
+ void LexTokenInternal(LexerToken &Result);
+
+ /// FormTokenWithChars - When we lex a token, we have identified a span
+ /// starting at BufferPtr, going to TokEnd that forms the token. This method
+ /// takes that range and assigns it to the token as its location and size. In
+ /// addition, since tokens cannot overlap, this also updates BufferPtr to be
+ /// TokEnd.
+ void FormTokenWithChars(LexerToken &Result, const char *TokEnd) {
+ Result.setLocation(getSourceLocation(BufferPtr));
+ Result.setLength(TokEnd-BufferPtr);
+ BufferPtr = TokEnd;
+ }
+
+ /// isNextPPTokenLParen - Return 1 if the next unexpanded token will return a
+ /// tok::l_paren token, 0 if it is something else and 2 if there are no more
+ /// tokens in the buffer controlled by this lexer.
+ unsigned isNextPPTokenLParen();
+
+ //===--------------------------------------------------------------------===//
+ // Lexer character reading interfaces.
+
+ // This lexer is built on two interfaces for reading characters, both of which
+ // automatically provide phase 1/2 translation. getAndAdvanceChar is used
+ // when we know that we will be reading a character from the input buffer and
+ // that this character will be part of the result token. This occurs in (f.e.)
+ // string processing, because we know we need to read until we find the
+ // closing '"' character.
+ //
+ // The second interface is the combination of PeekCharAndSize with
+ // ConsumeChar. PeekCharAndSize reads a phase 1/2 translated character,
+ // returning it and its size. If the lexer decides that this character is
+ // part of the current token, it calls ConsumeChar on it. This two stage
+ // approach allows us to emit diagnostics for characters (e.g. warnings about
+ // trigraphs), knowing that they only are emitted if the character is
+ // consumed.
+
+
+ /// getAndAdvanceChar - Read a single 'character' from the specified buffer,
+ /// advance over it, and return it. This is tricky in several cases. Here we
+ /// just handle the trivial case and fall-back to the non-inlined
+ /// getCharAndSizeSlow method to handle the hard case.
+ inline char getAndAdvanceChar(const char *&Ptr, LexerToken &Tok) {
+ // If this is not a trigraph and not a UCN or escaped newline, return
+ // quickly.
+ if (Ptr[0] != '?' && Ptr[0] != '\\') return *Ptr++;
+
+ unsigned Size = 0;
+ char C = getCharAndSizeSlow(Ptr, Size, &Tok);
+ Ptr += Size;
+ return C;
+ }
+
+ /// ConsumeChar - When a character (identified by PeekCharAndSize) is consumed
+ /// and added to a given token, check to see if there are diagnostics that
+ /// need to be emitted or flags that need to be set on the token. If so, do
+ /// it.
+ const char *ConsumeChar(const char *Ptr, unsigned Size, LexerToken &Tok) {
+ // Normal case, we consumed exactly one token. Just return it.
+ if (Size == 1)
+ return Ptr+Size;
+
+ // Otherwise, re-lex the character with a current token, allowing
+ // diagnostics to be emitted and flags to be set.
+ Size = 0;
+ getCharAndSizeSlow(Ptr, Size, &Tok);
+ return Ptr+Size;
+ }
+
+ /// getCharAndSize - Peek a single 'character' from the specified buffer,
+ /// get its size, and return it. This is tricky in several cases. Here we
+ /// just handle the trivial case and fall-back to the non-inlined
+ /// getCharAndSizeSlow method to handle the hard case.
+ inline char getCharAndSize(const char *Ptr, unsigned &Size) {
+ // If this is not a trigraph and not a UCN or escaped newline, return
+ // quickly.
+ if (Ptr[0] != '?' && Ptr[0] != '\\') {
+ Size = 1;
+ return *Ptr;
+ }
+
+ Size = 0;
+ return getCharAndSizeSlow(Ptr, Size);
+ }
+
+ /// getCharAndSizeSlow - Handle the slow/uncommon case of the getCharAndSize
+ /// method.
+ char getCharAndSizeSlow(const char *Ptr, unsigned &Size, LexerToken *Tok = 0);
+
+ /// getCharAndSizeNoWarn - Like the getCharAndSize method, but does not ever
+ /// emit a warning.
+ static inline char getCharAndSizeNoWarn(const char *Ptr, unsigned &Size,
+ const LangOptions &Features) {
+ // If this is not a trigraph and not a UCN or escaped newline, return
+ // quickly.
+ if (Ptr[0] != '?' && Ptr[0] != '\\') {
+ Size = 1;
+ return *Ptr;
+ }
+
+ Size = 0;
+ return getCharAndSizeSlowNoWarn(Ptr, Size, Features);
+ }
+
+ /// getCharAndSizeSlowNoWarn - Same as getCharAndSizeSlow, but never emits a
+ /// diagnostic.
+ static char getCharAndSizeSlowNoWarn(const char *Ptr, unsigned &Size,
+ const LangOptions &Features);
+
+ //===--------------------------------------------------------------------===//
+ // #if directive handling.
+
+ /// pushConditionalLevel - When we enter a #if directive, this keeps track of
+ /// what we are currently in for diagnostic emission (e.g. #if with missing
+ /// #endif).
+ void pushConditionalLevel(SourceLocation DirectiveStart, bool WasSkipping,
+ bool FoundNonSkip, bool FoundElse) {
+ PPConditionalInfo CI;
+ CI.IfLoc = DirectiveStart;
+ CI.WasSkipping = WasSkipping;
+ CI.FoundNonSkip = FoundNonSkip;
+ CI.FoundElse = FoundElse;
+ ConditionalStack.push_back(CI);
+ }
+ void pushConditionalLevel(const PPConditionalInfo &CI) {
+ ConditionalStack.push_back(CI);
+ }
+
+ /// popConditionalLevel - Remove an entry off the top of the conditional
+ /// stack, returning information about it. If the conditional stack is empty,
+ /// this returns true and does not fill in the arguments.
+ bool popConditionalLevel(PPConditionalInfo &CI) {
+ if (ConditionalStack.empty()) return true;
+ CI = ConditionalStack.back();
+ ConditionalStack.pop_back();
+ return false;
+ }
+
+ /// peekConditionalLevel - Return the top of the conditional stack. This
+ /// requires that there be a conditional active.
+ PPConditionalInfo &peekConditionalLevel() {
+ assert(!ConditionalStack.empty() && "No conditionals active!");
+ return ConditionalStack.back();
+ }
+
+ unsigned getConditionalStackDepth() const { return ConditionalStack.size(); }
+
+ //===--------------------------------------------------------------------===//
+ // Other lexer functions.
+
+ // Helper functions to lex the remainder of a token of the specific type.
+ void LexIdentifier (LexerToken &Result, const char *CurPtr);
+ void LexNumericConstant (LexerToken &Result, const char *CurPtr);
+ void LexStringLiteral (LexerToken &Result, const char *CurPtr,bool Wide);
+ void LexAngledStringLiteral(LexerToken &Result, const char *CurPtr);
+ void LexCharConstant (LexerToken &Result, const char *CurPtr);
+ bool LexEndOfFile (LexerToken &Result, const char *CurPtr);
+
+ void SkipWhitespace (LexerToken &Result, const char *CurPtr);
+ bool SkipBCPLComment (LexerToken &Result, const char *CurPtr);
+ bool SkipBlockComment (LexerToken &Result, const char *CurPtr);
+ bool SaveBCPLComment (LexerToken &Result, const char *CurPtr);
+
+ /// LexIncludeFilename - After the preprocessor has parsed a #include, lex and
+ /// (potentially) macro expand the filename. If the sequence parsed is not
+ /// lexically legal, emit a diagnostic and return a result EOM token.
+ void LexIncludeFilename(LexerToken &Result);
+};
+
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/LexerToken.h b/include/clang/Lex/LexerToken.h
new file mode 100644
index 0000000..119a1d9
--- /dev/null
+++ b/include/clang/Lex/LexerToken.h
@@ -0,0 +1,137 @@
+//===--- LexerToken.h - Token interface -------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the LexerToken interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LEXERTOKEN_H
+#define LLVM_CLANG_LEXERTOKEN_H
+
+#include "clang/Basic/TokenKinds.h"
+#include "clang/Basic/SourceLocation.h"
+
+namespace clang {
+
+class IdentifierInfo;
+
+/// LexerToken - This structure provides full information about a lexed token.
+/// It is not intended to be space efficient, it is intended to return as much
+/// information as possible about each returned token. This is expected to be
+/// compressed into a smaller form if memory footprint is important.
+class LexerToken {
+ /// The location and length of the token text itself.
+ SourceLocation Loc;
+ unsigned Length;
+
+ /// IdentifierInfo - If this was an identifier, this points to the uniqued
+ /// information about this identifier.
+ IdentifierInfo *IdentInfo;
+
+ /// Kind - The actual flavor of token this is.
+ ///
+ tok::TokenKind Kind : 8;
+
+ /// Flags - Bits we track about this token, members of the TokenFlags enum.
+ unsigned Flags : 8;
+public:
+
+ // Various flags set per token:
+ enum TokenFlags {
+ StartOfLine = 0x01, // At start of line or only after whitespace.
+ LeadingSpace = 0x02, // Whitespace exists before this token.
+ DisableExpand = 0x04, // This identifier may never be macro expanded.
+ NeedsCleaning = 0x08 // Contained an escaped newline or trigraph.
+ };
+
+ tok::TokenKind getKind() const { return Kind; }
+ void setKind(tok::TokenKind K) { Kind = K; }
+
+ /// getLocation - Return a source location identifier for the specified
+ /// offset in the current file.
+ SourceLocation getLocation() const { return Loc; }
+ unsigned getLength() const { return Length; }
+
+ void setLocation(SourceLocation L) { Loc = L; }
+ void setLength(unsigned Len) { Length = Len; }
+
+ const char *getName() const { return getTokenName(Kind); }
+
+ /// startToken - Reset all flags to cleared.
+ ///
+ void startToken() {
+ Flags = 0;
+ IdentInfo = 0;
+ Loc = SourceLocation();
+ }
+
+ IdentifierInfo *getIdentifierInfo() const { return IdentInfo; }
+ void setIdentifierInfo(IdentifierInfo *II) {
+ IdentInfo = II;
+ }
+
+ /// setFlag - Set the specified flag.
+ void setFlag(TokenFlags Flag) {
+ Flags |= Flag;
+ }
+
+ /// clearFlag - Unset the specified flag.
+ void clearFlag(TokenFlags Flag) {
+ Flags &= ~Flag;
+ }
+
+ /// setFlagValue - Set a flag to either true or false.
+ void setFlagValue(TokenFlags Flag, bool Val) {
+ if (Val)
+ setFlag(Flag);
+ else
+ clearFlag(Flag);
+ }
+
+ /// isAtStartOfLine - Return true if this token is at the start of a line.
+ ///
+ bool isAtStartOfLine() const { return Flags & StartOfLine; }
+
+ /// hasLeadingSpace - Return true if this token has whitespace before it.
+ ///
+ bool hasLeadingSpace() const { return Flags & LeadingSpace; }
+
+ /// isExpandDisabled - Return true if this identifier token should never
+ /// be expanded in the future, due to C99 6.10.3.4p2.
+ bool isExpandDisabled() const { return Flags & DisableExpand; }
+
+ /// needsCleaning - Return true if this token has trigraphs or escaped
+ /// newlines in it.
+ ///
+ bool needsCleaning() const { return Flags & NeedsCleaning; }
+};
+
+/// PPConditionalInfo - Information about the conditional stack (#if directives)
+/// currently active.
+struct PPConditionalInfo {
+ /// IfLoc - Location where the conditional started.
+ ///
+ SourceLocation IfLoc;
+
+ /// WasSkipping - True if this was contained in a skipping directive, e.g.
+ /// in a "#if 0" block.
+ bool WasSkipping;
+
+ /// FoundNonSkip - True if we have emitted tokens already, and now we're in
+ /// an #else block or something. Only useful in Skipping blocks.
+ bool FoundNonSkip;
+
+ /// FoundElse - True if we've seen a #else in this block. If so,
+ /// #elif/#else directives are not allowed.
+ bool FoundElse;
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h
new file mode 100644
index 0000000..adeac18
--- /dev/null
+++ b/include/clang/Lex/LiteralSupport.h
@@ -0,0 +1,156 @@
+//===--- LiteralSupport.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Steve Naroff and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the NumericLiteralParser, CharLiteralParser, and
+// StringLiteralParser interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_LITERALSUPPORT_H
+#define CLANG_LITERALSUPPORT_H
+
+#include <string>
+#include "llvm/ADT/SmallString.h"
+
+namespace llvm {
+ class APInt;
+}
+
+namespace clang {
+
+class Diagnostic;
+class Preprocessor;
+class LexerToken;
+class SourceLocation;
+class TargetInfo;
+
+/// NumericLiteralParser - This performs strict semantic analysis of the content
+/// of a ppnumber, classifying it as either integer, floating, or erroneous,
+/// determines the radix of the value and can convert it to a useful value.
+class NumericLiteralParser {
+ Preprocessor &PP; // needed for diagnostics
+
+ const char *const ThisTokBegin;
+ const char *const ThisTokEnd;
+ const char *DigitsBegin, *SuffixBegin; // markers
+ const char *s; // cursor
+
+ unsigned radix;
+
+ bool saw_exponent, saw_period;
+ bool saw_float_suffix;
+
+public:
+ NumericLiteralParser(const char *begin, const char *end,
+ SourceLocation Loc, Preprocessor &PP);
+ bool hadError;
+ bool isUnsigned;
+ bool isLong; // This is also set for long long.
+ bool isLongLong;
+
+ bool isIntegerLiteral() const {
+ return !saw_period && !saw_exponent ? true : false;
+ }
+ bool isFloatingLiteral() const {
+ return saw_period || saw_exponent ? true : false;
+ }
+ bool hasSuffix() const {
+ return SuffixBegin != ThisTokEnd;
+ }
+
+ unsigned getRadix() const { return radix; }
+
+ /// GetIntegerValue - Convert this numeric literal value to an APInt that
+ /// matches Val's input width. If there is an overflow (i.e., if the unsigned
+ /// value read is larger than the APInt's bits will hold), set Val to the low
+ /// bits of the result and return true. Otherwise, return false.
+ bool GetIntegerValue(llvm::APInt &Val);
+
+ /// GetFloatValue - Convert this numeric literal to a float.
+ /// FIXME: the return value is fixed size - make more general.
+ float GetFloatValue();
+
+private:
+ void Diag(SourceLocation Loc, unsigned DiagID,
+ const std::string &M = std::string());
+
+ /// SkipHexDigits - Read and skip over any hex digits, up to End.
+ /// Return a pointer to the first non-hex digit or End.
+ const char *SkipHexDigits(const char *ptr) {
+ while (ptr != ThisTokEnd && isxdigit(*ptr))
+ ptr++;
+ return ptr;
+ }
+
+ /// SkipOctalDigits - Read and skip over any octal digits, up to End.
+ /// Return a pointer to the first non-hex digit or End.
+ const char *SkipOctalDigits(const char *ptr) {
+ while (ptr != ThisTokEnd && ((*ptr >= '0') && (*ptr <= '7')))
+ ptr++;
+ return ptr;
+ }
+
+ /// SkipDigits - Read and skip over any digits, up to End.
+ /// Return a pointer to the first non-hex digit or End.
+ const char *SkipDigits(const char *ptr) {
+ while (ptr != ThisTokEnd && isdigit(*ptr))
+ ptr++;
+ return ptr;
+ }
+
+ /// SkipBinaryDigits - Read and skip over any binary digits, up to End.
+ /// Return a pointer to the first non-binary digit or End.
+ const char *SkipBinaryDigits(const char *ptr) {
+ while (ptr != ThisTokEnd && (*ptr == '0' || *ptr == '1'))
+ ptr++;
+ return ptr;
+ }
+
+};
+
+/// CharLiteralParser - Perform interpretation and semantic analysis of a
+/// character literal.
+class CharLiteralParser {
+ unsigned Value;
+ bool IsWide;
+ bool HadError;
+public:
+ CharLiteralParser(const char *begin, const char *end,
+ SourceLocation Loc, Preprocessor &PP);
+
+ bool hadError() const { return HadError; }
+ bool isWide() const { return IsWide; }
+ unsigned getValue() const { return Value; }
+};
+
+/// StringLiteralParser - This decodes string escape characters and performs
+/// wide string analysis and Translation Phase #6 (concatenation of string
+/// literals) (C99 5.1.1.2p1).
+class StringLiteralParser {
+ Preprocessor &PP;
+ TargetInfo &Target;
+
+ unsigned MaxTokenLength;
+ unsigned SizeBound;
+ unsigned wchar_tByteWidth;
+ llvm::SmallString<512> ResultBuf;
+ char *ResultPtr; // cursor
+public:
+ StringLiteralParser(const LexerToken *StringToks, unsigned NumStringToks,
+ Preprocessor &PP, TargetInfo &T);
+ bool hadError;
+ bool AnyWide;
+
+ const char *GetString() { return &ResultBuf[0]; }
+ unsigned GetStringLength() { return ResultPtr-&ResultBuf[0]; }
+};
+
+} // end namespace clang
+
+#endif
\ No newline at end of file
diff --git a/include/clang/Lex/MacroExpander.h b/include/clang/Lex/MacroExpander.h
new file mode 100644
index 0000000..8bb4ebf
--- /dev/null
+++ b/include/clang/Lex/MacroExpander.h
@@ -0,0 +1,179 @@
+//===--- MacroExpander.h - Lex from a macro expansion -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the MacroExpander and MacroArgs interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_MACROEXPANDER_H
+#define LLVM_CLANG_MACROEXPANDER_H
+
+#include "clang/Basic/SourceLocation.h"
+#include <vector>
+
+namespace clang {
+ class MacroInfo;
+ class Preprocessor;
+ class LexerToken;
+
+/// MacroArgs - An instance of this class captures information about
+/// the formal arguments specified to a function-like macro invocation.
+class MacroArgs {
+ /// NumUnexpArgTokens - The number of raw, unexpanded tokens for the
+ /// arguments. All of the actual argument tokens are allocated immediately
+ /// after the MacroArgs object in memory. This is all of the arguments
+ /// concatenated together, with 'EOF' markers at the end of each argument.
+ unsigned NumUnexpArgTokens;
+
+ /// PreExpArgTokens - Pre-expanded tokens for arguments that need them. Empty
+ /// if not yet computed. This includes the EOF marker at the end of the
+ /// stream.
+ std::vector<std::vector<LexerToken> > PreExpArgTokens;
+
+ /// StringifiedArgs - This contains arguments in 'stringified' form. If the
+ /// stringified form of an argument has not yet been computed, this is empty.
+ std::vector<LexerToken> StringifiedArgs;
+
+ /// VarargsElided - True if this is a C99 style varargs macro invocation and
+ /// there was no argument specified for the "..." argument. If the argument
+ /// was specified (even empty) or this isn't a C99 style varargs function, or
+ /// if in strict mode and the C99 varargs macro had only a ... argument, this
+ /// is false.
+ bool VarargsElided;
+
+ MacroArgs(unsigned NumToks, bool varargsElided)
+ : NumUnexpArgTokens(NumToks), VarargsElided(varargsElided) {}
+ ~MacroArgs() {}
+public:
+ /// MacroArgs ctor function - Create a new MacroArgs object with the specified
+ /// macro and argument info.
+ static MacroArgs *create(const MacroInfo *MI,
+ const LexerToken *UnexpArgTokens,
+ unsigned NumArgTokens, bool VarargsElided);
+
+ /// destroy - Destroy and deallocate the memory for this object.
+ ///
+ void destroy();
+
+ /// ArgNeedsPreexpansion - If we can prove that the argument won't be affected
+ /// by pre-expansion, return false. Otherwise, conservatively return true.
+ bool ArgNeedsPreexpansion(const LexerToken *ArgTok) const;
+
+ /// getUnexpArgument - Return a pointer to the first token of the unexpanded
+ /// token list for the specified formal.
+ ///
+ const LexerToken *getUnexpArgument(unsigned Arg) const;
+
+ /// getArgLength - Given a pointer to an expanded or unexpanded argument,
+ /// return the number of tokens, not counting the EOF, that make up the
+ /// argument.
+ static unsigned getArgLength(const LexerToken *ArgPtr);
+
+ /// getPreExpArgument - Return the pre-expanded form of the specified
+ /// argument.
+ const std::vector<LexerToken> &
+ getPreExpArgument(unsigned Arg, Preprocessor &PP);
+
+ /// getStringifiedArgument - Compute, cache, and return the specified argument
+ /// that has been 'stringified' as required by the # operator.
+ const LexerToken &getStringifiedArgument(unsigned ArgNo, Preprocessor &PP);
+
+ /// getNumArguments - Return the number of arguments passed into this macro
+ /// invocation.
+ unsigned getNumArguments() const { return NumUnexpArgTokens; }
+
+
+ /// isVarargsElidedUse - Return true if this is a C99 style varargs macro
+ /// invocation and there was no argument specified for the "..." argument. If
+ /// the argument was specified (even empty) or this isn't a C99 style varargs
+ /// function, or if in strict mode and the C99 varargs macro had only a ...
+ /// argument, this returns false.
+ bool isVarargsElidedUse() const { return VarargsElided; }
+};
+
+
+/// MacroExpander - This implements a lexer that returns token from a macro body
+/// or token stream instead of lexing from a character buffer.
+///
+class MacroExpander {
+ /// Macro - The macro we are expanding from. This is null if expanding a
+ /// token stream.
+ ///
+ MacroInfo *Macro;
+
+ /// ActualArgs - The actual arguments specified for a function-like macro, or
+ /// null. The MacroExpander owns the pointed-to object.
+ MacroArgs *ActualArgs;
+
+ /// PP - The current preprocessor object we are expanding for.
+ ///
+ Preprocessor &PP;
+
+ /// MacroTokens - This is the pointer to an array of tokens that the macro is
+ /// defined to, with arguments expanded for function-like macros. If this is
+ /// a token stream, these are the tokens we are returning.
+ const LexerToken *MacroTokens;
+
+ /// NumMacroTokens - This is the length of the MacroTokens array.
+ ///
+ unsigned NumMacroTokens;
+
+ /// CurToken - This is the next token that Lex will return.
+ ///
+ unsigned CurToken;
+
+ /// InstantiateLoc - The source location where this macro was instantiated.
+ ///
+ SourceLocation InstantiateLoc;
+
+ /// Lexical information about the expansion point of the macro: the identifier
+ /// that the macro expanded from had these properties.
+ bool AtStartOfLine, HasLeadingSpace;
+
+ MacroExpander(const MacroExpander&); // DO NOT IMPLEMENT
+ void operator=(const MacroExpander&); // DO NOT IMPLEMENT
+public:
+ /// Create a macro expander for the specified macro with the specified actual
+ /// arguments. Note that this ctor takes ownership of the ActualArgs pointer.
+ MacroExpander(LexerToken &Tok, MacroArgs *ActualArgs, Preprocessor &PP);
+
+ /// Create a macro expander for the specified token stream. This does not
+ /// take ownership of the specified token vector.
+ MacroExpander(const LexerToken *TokArray, unsigned NumToks, Preprocessor &PP);
+ ~MacroExpander();
+
+ /// isNextTokenLParen - If the next token lexed will pop this macro off the
+ /// expansion stack, return 2. If the next unexpanded token is a '(', return
+ /// 1, otherwise return 0.
+ unsigned isNextTokenLParen() const;
+
+ /// Lex - Lex and return a token from this macro stream.
+ void Lex(LexerToken &Tok);
+
+private:
+ /// isAtEnd - Return true if the next lex call will pop this macro off the
+ /// include stack.
+ bool isAtEnd() const {
+ return CurToken == NumMacroTokens;
+ }
+
+ /// PasteTokens - Tok is the LHS of a ## operator, and CurToken is the ##
+ /// operator. Read the ## and RHS, and paste the LHS/RHS together. If there
+ /// are is another ## after it, chomp it iteratively. Return the result as
+ /// Tok.
+ void PasteTokens(LexerToken &Tok);
+
+ /// Expand the arguments of a function-like macro so that we can quickly
+ /// return preexpanded tokens from MacroTokens.
+ void ExpandFunctionArguments();
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h
new file mode 100644
index 0000000..ad489de
--- /dev/null
+++ b/include/clang/Lex/MacroInfo.h
@@ -0,0 +1,186 @@
+//===--- MacroInfo.h - Information about #defined identifiers ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the MacroInfo interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_MACROINFO_H
+#define LLVM_CLANG_MACROINFO_H
+
+#include "clang/Lex/LexerToken.h"
+#include <vector>
+
+namespace clang {
+ class Preprocessor;
+
+/// MacroInfo - Each identifier that is #define'd has an instance of this class
+/// associated with it, used to implement macro expansion.
+class MacroInfo {
+ //===--------------------------------------------------------------------===//
+ // State set when the macro is defined.
+
+ /// Location - This is the place the macro is defined.
+ SourceLocation Location;
+
+ /// Arguments - The list of arguments for a function-like macro. This can be
+ /// empty, for, e.g. "#define X()". In a C99-style variadic macro, this
+ /// includes the __VA_ARGS__ identifier on the list.
+ std::vector<IdentifierInfo*> Arguments;
+
+ /// ReplacementTokens - This is the list of tokens that the macro is defined
+ /// to.
+ std::vector<LexerToken> ReplacementTokens;
+
+ /// IsFunctionLike - True if this macro is a function-like macro, false if it
+ /// is an object-like macro.
+ bool IsFunctionLike : 1;
+
+ /// IsC99Varargs - True if this macro is of the form "#define X(...)" or
+ /// "#define X(Y,Z,...)". The __VA_ARGS__ token should be replaced with the
+ /// contents of "..." in an invocation.
+ bool IsC99Varargs : 1;
+
+ /// IsGNUVarargs - True if this macro is of the form "#define X(a...)". The
+ /// "a" identifier in th replacement list will be replaced with all arguments
+ /// of the macro starting with the specified one.
+ bool IsGNUVarargs : 1;
+
+ /// IsBuiltinMacro - True if this is a builtin macro, such as __LINE__, and if
+ /// it has not yet been redefined or undefined.
+ bool IsBuiltinMacro : 1;
+
+ /// IsTargetSpecific - True if this is a target-specific macro defined with
+ /// #define_target.
+ bool IsTargetSpecific : 1;
+private:
+ //===--------------------------------------------------------------------===//
+ // State that changes as the macro is used.
+
+ /// IsDisabled - True if we have started an expansion of this macro already.
+ /// This disbles recursive expansion, which would be quite bad for things like
+ /// #define A A.
+ bool IsDisabled : 1;
+
+ /// IsUsed - True if this macro is either defined in the main file and has
+ /// been used, or if it is not defined in the main file. This is used to
+ /// emit -Wunused-macros diagnostics.
+ bool IsUsed : 1;
+public:
+ MacroInfo(SourceLocation DefLoc);
+
+ /// getDefinitionLoc - Return the location that the macro was defined at.
+ ///
+ SourceLocation getDefinitionLoc() const { return Location; }
+
+ /// isIdenticalTo - Return true if the specified macro definition is equal to
+ /// this macro in spelling, arguments, and whitespace. This is used to emit
+ /// duplicate definition warnings. This implements the rules in C99 6.10.3.
+ bool isIdenticalTo(const MacroInfo &Other, Preprocessor &PP) const;
+
+ /// setIsBuiltinMacro - Set or clear the isBuiltinMacro flag.
+ ///
+ void setIsBuiltinMacro(bool Val = true) {
+ IsBuiltinMacro = Val;
+ }
+
+ /// setIsTargetSpecific - Set or clear the IsTargetSpecific flag.
+ ///
+ void setIsTargetSpecific(bool Val = true) {
+ IsTargetSpecific = Val;
+ }
+ bool isTargetSpecific() const { return IsTargetSpecific; }
+
+ /// setIsUsed - Set the value of the IsUsed flag.
+ ///
+ void setIsUsed(bool Val) {
+ IsUsed = Val;
+ }
+
+ /// addArgument - Add an argument to the list of formal arguments for this
+ /// function-like macro.
+ void addArgument(IdentifierInfo *Arg) {
+ Arguments.push_back(Arg);
+ }
+
+ /// getArgumentNum - Return the argument number of the specified identifier,
+ /// or -1 if the identifier is not a formal argument identifier.
+ int getArgumentNum(IdentifierInfo *Arg) {
+ for (unsigned i = 0, e = Arguments.size(); i != e; ++i)
+ if (Arguments[i] == Arg) return i;
+ return -1;
+ }
+
+ /// Arguments - The list of arguments for a function-like macro. This can be
+ /// empty, for, e.g. "#define X()".
+ typedef std::vector<IdentifierInfo*>::const_iterator arg_iterator;
+ arg_iterator arg_begin() const { return Arguments.begin(); }
+ arg_iterator arg_end() const { return Arguments.end(); }
+ unsigned getNumArgs() const { return Arguments.size(); }
+
+ /// Function/Object-likeness. Keep track of whether this macro has formal
+ /// parameters.
+ void setIsFunctionLike() { IsFunctionLike = true; }
+ bool isFunctionLike() const { return IsFunctionLike; }
+ bool isObjectLike() const { return !IsFunctionLike; }
+
+ /// Varargs querying methods. This can only be set for function-like macros.
+ void setIsC99Varargs() { IsC99Varargs = true; }
+ void setIsGNUVarargs() { IsGNUVarargs = true; }
+ bool isC99Varargs() const { return IsC99Varargs; }
+ bool isGNUVarargs() const { return IsGNUVarargs; }
+ bool isVariadic() const { return IsC99Varargs | IsGNUVarargs; }
+
+ /// isBuiltinMacro - Return true if this macro is a builtin macro, such as
+ /// __LINE__, which requires processing before expansion.
+ bool isBuiltinMacro() const { return IsBuiltinMacro; }
+
+ /// isUsed - Return false if this macro is defined in the main file and has
+ /// not yet been used.
+ bool isUsed() const { return IsUsed; }
+
+ /// getNumTokens - Return the number of tokens that this macro expands to.
+ ///
+ unsigned getNumTokens() const {
+ return ReplacementTokens.size();
+ }
+
+ const LexerToken &getReplacementToken(unsigned Tok) const {
+ assert(Tok < ReplacementTokens.size() && "Invalid token #");
+ return ReplacementTokens[Tok];
+ }
+
+ const std::vector<LexerToken> &getReplacementTokens() const {
+ return ReplacementTokens;
+ }
+
+ /// AddTokenToBody - Add the specified token to the replacement text for the
+ /// macro.
+ void AddTokenToBody(const LexerToken &Tok) {
+ ReplacementTokens.push_back(Tok);
+ }
+
+ /// isEnabled - Return true if this macro is enabled: in other words, that we
+ /// are not currently in an expansion of this macro.
+ bool isEnabled() const { return !IsDisabled; }
+
+ void EnableMacro() {
+ assert(IsDisabled && "Cannot enable an already-enabled macro!");
+ IsDisabled = false;
+ }
+
+ void DisableMacro() {
+ assert(!IsDisabled && "Cannot disable an already-disabled macro!");
+ IsDisabled = true;
+ }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/MultipleIncludeOpt.h b/include/clang/Lex/MultipleIncludeOpt.h
new file mode 100644
index 0000000..e4ec5b8
--- /dev/null
+++ b/include/clang/Lex/MultipleIncludeOpt.h
@@ -0,0 +1,107 @@
+//===--- MultipleIncludeOpt.h - Header Multiple-Include Optzn ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the MultipleIncludeOpt interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_MULTIPLEINCLUDEOPT_H
+#define LLVM_CLANG_MULTIPLEINCLUDEOPT_H
+
+namespace clang {
+class IdentifierInfo;
+
+/// MultipleIncludeOpt - This class implements the simple state machine that the
+/// Lexer class uses to detect files subject to the 'multiple-include'
+/// optimization. The public methods in this class are triggered by various
+/// events that occur when a file is lexed, and after the entire file is lexed,
+/// information about which macro (if any) controls the header is returned.
+class MultipleIncludeOpt {
+ /// ReadAnyTokens - This is set to false when a file is first opened and true
+ /// any time a token is returned to the client or a (non-multiple-include)
+ /// directive is parsed. When the final #endif is parsed this is reset back
+ /// to false, that way any tokens before the first #ifdef or after the last
+ /// #endif can be easily detected.
+ bool ReadAnyTokens;
+
+ /// TheMacro - The controlling macro for a file, if valid.
+ ///
+ const IdentifierInfo *TheMacro;
+public:
+ MultipleIncludeOpt() : ReadAnyTokens(false), TheMacro(0) {}
+
+ /// Invalidate - Permenantly mark this file as not being suitable for the
+ /// include-file optimization.
+ void Invalidate() {
+ // If we have read tokens but have no controlling macro, the state-machine
+ // below can never "accept".
+ ReadAnyTokens = true;
+ TheMacro = 0;
+ }
+
+ /// getHasReadAnyTokensVal - This is used for the #ifndef hande-shake at the
+ /// top of the file when reading preprocessor directives. Otherwise, reading
+ /// the "ifndef x" would count as reading tokens.
+ bool getHasReadAnyTokensVal() const { return ReadAnyTokens; }
+
+ // If a token is read, remember that we have seen a side-effect in this file.
+ void ReadToken() { ReadAnyTokens = true; }
+
+ /// EnterTopLevelIFNDEF - When entering a top-level #ifndef directive (or the
+ /// "#if !defined" equivalent) without any preceding tokens, this method is
+ /// called.
+ void EnterTopLevelIFNDEF(const IdentifierInfo *M) {
+ // Note, we don't care about the input value of 'ReadAnyTokens'. The caller
+ // ensures that this is only called if there are no tokens read before the
+ // #ifndef.
+
+ // If the macro is already set, this is after the top-level #endif.
+ if (TheMacro)
+ return Invalidate();
+
+ // Remember that we're in the #if and that we have the macro.
+ ReadAnyTokens = true;
+ TheMacro = M;
+ }
+
+ /// FoundTopLevelElse - This is invoked when an #else/#elif directive is found
+ /// in the top level conditional in the file.
+ void FoundTopLevelElse() {
+ /// If a #else directive is found at the top level, there is a chunk of the
+ /// file not guarded by the controlling macro.
+ Invalidate();
+ }
+
+ /// ExitTopLevelConditional - This method is called when the lexer exits the
+ /// top-level conditional.
+ void ExitTopLevelConditional() {
+ // If we have a macro, that means the top of the file was ok. Set our state
+ // back to "not having read any tokens" so we can detect anything after the
+ // #endif.
+ if (!TheMacro) return Invalidate();
+
+ // At this point, we haven't "read any tokens" but we do have a controlling
+ // macro.
+ ReadAnyTokens = false;
+ }
+
+ /// GetControllingMacroAtEndOfFile - Once the entire file has been lexed, if
+ /// there is a controlling macro, return it.
+ const IdentifierInfo *GetControllingMacroAtEndOfFile() const {
+ // If we haven't read any tokens after the #endif, return the controlling
+ // macro if it's valid (if it isn't, it will be null).
+ if (!ReadAnyTokens)
+ return TheMacro;
+ return 0;
+ }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h
new file mode 100644
index 0000000..def8072
--- /dev/null
+++ b/include/clang/Lex/PPCallbacks.h
@@ -0,0 +1,53 @@
+//===--- PPCallbacks.h - Callbacks for Preprocessor actions -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the PPCallbacks interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LEX_PPCALLBACKS_H
+#define LLVM_CLANG_LEX_PPCALLBACKS_H
+
+#include "clang/Lex/DirectoryLookup.h"
+#include "clang/Basic/SourceLocation.h"
+#include <string>
+
+namespace clang {
+ class SourceLocation;
+
+/// PPCallbacks - This interface provides a way to observe the actions of the
+/// preprocessor as it does its thing. Clients can define their hooks here to
+/// implement preprocessor level tools.
+class PPCallbacks {
+public:
+ virtual ~PPCallbacks();
+
+ enum FileChangeReason {
+ EnterFile, ExitFile, SystemHeaderPragma, RenameFile
+ };
+
+ /// FileChanged - This callback is invoked whenever a source file is
+ /// entered or exited. The SourceLocation indicates the new location, and
+ /// EnteringFile indicates whether this is because we are entering a new
+ /// #include'd file (when true) or whether we're exiting one because we ran
+ /// off the end (when false).
+ virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
+ DirectoryLookup::DirType FileType) {
+ }
+
+ /// Ident - This callback is invoked when a #ident or #sccs directive is read.
+ ///
+ virtual void Ident(SourceLocation Loc, const std::string &str) {
+ }
+
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/Pragma.h b/include/clang/Lex/Pragma.h
new file mode 100644
index 0000000..5e35ae0
--- /dev/null
+++ b/include/clang/Lex/Pragma.h
@@ -0,0 +1,82 @@
+//===--- Pragma.h - Pragma registration and handling ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the PragmaHandler and PragmaTable interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PRAGMA_H
+#define LLVM_CLANG_PRAGMA_H
+
+#include <cassert>
+#include <vector>
+
+namespace clang {
+ class Preprocessor;
+ class LexerToken;
+ class IdentifierInfo;
+ class PragmaNamespace;
+
+/// PragmaHandler - Instances of this interface defined to handle the various
+/// pragmas that the language front-end uses. Each handler optionally has a
+/// name (e.g. "pack") and the HandlePragma method is invoked when a pragma with
+/// that identifier is found. If a handler does not match any of the declared
+/// pragmas the handler with a null identifier is invoked, if it exists.
+///
+/// Note that the PragmaNamespace class can be used to subdivide pragmas, e.g.
+/// we treat "#pragma STDC" and "#pragma GCC" as namespaces that contain other
+/// pragmas.
+class PragmaHandler {
+ const IdentifierInfo *Name;
+public:
+ PragmaHandler(const IdentifierInfo *name) : Name(name) {}
+ virtual ~PragmaHandler();
+
+ const IdentifierInfo *getName() const { return Name; }
+ virtual void HandlePragma(Preprocessor &PP, LexerToken &FirstToken) = 0;
+
+ /// getIfNamespace - If this is a namespace, return it. This is equivalent to
+ /// using a dynamic_cast, but doesn't require RTTI.
+ virtual PragmaNamespace *getIfNamespace() { return 0; }
+};
+
+/// PragmaNamespace - This PragmaHandler subdivides the namespace of pragmas,
+/// allowing hierarchical pragmas to be defined. Common examples of namespaces
+/// are "#pragma GCC", "#pragma STDC", and "#pragma omp", but any namespaces may
+/// be (potentially recursively) defined.
+class PragmaNamespace : public PragmaHandler {
+ /// Handlers - This is the list of handlers in this namespace.
+ ///
+ std::vector<PragmaHandler*> Handlers;
+public:
+ PragmaNamespace(const IdentifierInfo *Name) : PragmaHandler(Name) {}
+ virtual ~PragmaNamespace();
+
+ /// FindHandler - Check to see if there is already a handler for the
+ /// specified name. If not, return the handler for the null identifier if it
+ /// exists, otherwise return null. If IgnoreNull is true (the default) then
+ /// the null handler isn't returned on failure to match.
+ PragmaHandler *FindHandler(const IdentifierInfo *Name,
+ bool IgnoreNull = true) const;
+
+ /// AddPragma - Add a pragma to this namespace.
+ ///
+ void AddPragma(PragmaHandler *Handler) {
+ Handlers.push_back(Handler);
+ }
+
+ virtual void HandlePragma(Preprocessor &PP, LexerToken &FirstToken);
+
+ virtual PragmaNamespace *getIfNamespace() { return this; }
+};
+
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
new file mode 100644
index 0000000..e3aff76
--- /dev/null
+++ b/include/clang/Lex/Preprocessor.h
@@ -0,0 +1,454 @@
+//===--- Preprocessor.h - C Language Family Preprocessor --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the Preprocessor interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LEX_PREPROCESSOR_H
+#define LLVM_CLANG_LEX_PREPROCESSOR_H
+
+#include "clang/Lex/IdentifierTable.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Lex/MacroExpander.h"
+#include "clang/Basic/SourceLocation.h"
+
+namespace clang {
+
+class SourceManager;
+class FileManager;
+class FileEntry;
+class HeaderSearch;
+class PragmaNamespace;
+class PragmaHandler;
+class ScratchBuffer;
+class TargetInfo;
+class PPCallbacks;
+class DirectoryLookup;
+
+/// Preprocessor - This object forms engages in a tight little dance to
+/// efficiently preprocess tokens. Lexers know only about tokens within a
+/// single source file, and don't know anything about preprocessor-level issues
+/// like the #include stack, token expansion, etc.
+///
+class Preprocessor {
+ Diagnostic &Diags;
+ const LangOptions &Features;
+ TargetInfo &Target;
+ FileManager &FileMgr;
+ SourceManager &SourceMgr;
+ ScratchBuffer *ScratchBuf;
+ HeaderSearch &HeaderInfo;
+
+ /// Identifiers for builtin macros and other builtins.
+ IdentifierInfo *Ident__LINE__, *Ident__FILE__; // __LINE__, __FILE__
+ IdentifierInfo *Ident__DATE__, *Ident__TIME__; // __DATE__, __TIME__
+ IdentifierInfo *Ident__INCLUDE_LEVEL__; // __INCLUDE_LEVEL__
+ IdentifierInfo *Ident__BASE_FILE__; // __BASE_FILE__
+ IdentifierInfo *Ident__TIMESTAMP__; // __TIMESTAMP__
+ IdentifierInfo *Ident_Pragma, *Ident__VA_ARGS__; // _Pragma, __VA_ARGS__
+
+ SourceLocation DATELoc, TIMELoc;
+
+ enum {
+ /// MaxIncludeStackDepth - Maximum depth of #includes.
+ MaxAllowedIncludeStackDepth = 200
+ };
+
+ // State that is set before the preprocessor begins.
+ bool KeepComments : 1;
+ bool KeepMacroComments : 1;
+
+ // State that changes while the preprocessor runs:
+ bool DisableMacroExpansion : 1; // True if macro expansion is disabled.
+ bool InMacroArgs : 1; // True if parsing fn macro invocation args.
+
+ /// Identifiers - This is mapping/lookup information for all identifiers in
+ /// the program, including program keywords.
+ IdentifierTable Identifiers;
+
+ /// PragmaHandlers - This tracks all of the pragmas that the client registered
+ /// with this preprocessor.
+ PragmaNamespace *PragmaHandlers;
+
+ /// CurLexer - This is the current top of the stack that we're lexing from if
+ /// not expanding a macro. One of CurLexer and CurMacroExpander must be null.
+ Lexer *CurLexer;
+
+ /// CurLookup - The DirectoryLookup structure used to find the current
+ /// FileEntry, if CurLexer is non-null and if applicable. This allows us to
+ /// implement #include_next and find directory-specific properties.
+ const DirectoryLookup *CurDirLookup;
+
+ /// CurMacroExpander - This is the current macro we are expanding, if we are
+ /// expanding a macro. One of CurLexer and CurMacroExpander must be null.
+ MacroExpander *CurMacroExpander;
+
+ /// IncludeMacroStack - This keeps track of the stack of files currently
+ /// #included, and macros currently being expanded from, not counting
+ /// CurLexer/CurMacroExpander.
+ struct IncludeStackInfo {
+ Lexer *TheLexer;
+ const DirectoryLookup *TheDirLookup;
+ MacroExpander *TheMacroExpander;
+ IncludeStackInfo(Lexer *L, const DirectoryLookup *D, MacroExpander *M)
+ : TheLexer(L), TheDirLookup(D), TheMacroExpander(M) {
+ }
+ };
+ std::vector<IncludeStackInfo> IncludeMacroStack;
+
+ /// Callbacks - These are actions invoked when some preprocessor activity is
+ /// encountered (e.g. a file is #included, etc).
+ PPCallbacks *Callbacks;
+
+ // Various statistics we track for performance analysis.
+ unsigned NumDirectives, NumIncluded, NumDefined, NumUndefined, NumPragma;
+ unsigned NumIf, NumElse, NumEndif;
+ unsigned NumEnteredSourceFiles, MaxIncludeStackDepth;
+ unsigned NumMacroExpanded, NumFnMacroExpanded, NumBuiltinMacroExpanded;
+ unsigned NumFastMacroExpanded, NumTokenPaste, NumFastTokenPaste;
+ unsigned NumSkipped;
+public:
+ Preprocessor(Diagnostic &diags, const LangOptions &opts, TargetInfo &target,
+ SourceManager &SM, HeaderSearch &Headers);
+ ~Preprocessor();
+
+ Diagnostic &getDiagnostics() const { return Diags; }
+ const LangOptions &getLangOptions() const { return Features; }
+ TargetInfo &getTargetInfo() const { return Target; }
+ FileManager &getFileManager() const { return FileMgr; }
+ SourceManager &getSourceManager() const { return SourceMgr; }
+ HeaderSearch &getHeaderSearchInfo() const { return HeaderInfo; }
+
+ IdentifierTable &getIdentifierTable() { return Identifiers; }
+
+ /// SetCommentRetentionState - Control whether or not the preprocessor retains
+ /// comments in output.
+ void SetCommentRetentionState(bool KeepComments, bool KeepMacroComments) {
+ this->KeepComments = KeepComments | KeepMacroComments;
+ this->KeepMacroComments = KeepMacroComments;
+ }
+
+ bool getCommentRetentionState() const { return KeepComments; }
+
+ /// isCurrentLexer - Return true if we are lexing directly from the specified
+ /// lexer.
+ bool isCurrentLexer(const Lexer *L) const {
+ return CurLexer == L;
+ }
+
+ /// isInPrimaryFile - Return true if we're in the top-level file, not in a
+ /// #include.
+ bool isInPrimaryFile() const;
+
+ /// getCurrentLexer - Return the current file lexer being lexed from. Note
+ /// that this ignores any potentially active macro expansions and _Pragma
+ /// expansions going on at the time.
+ Lexer *getCurrentFileLexer() const;
+
+ /// getPPCallbacks/SetPPCallbacks - Accessors for preprocessor callbacks.
+ ///
+ PPCallbacks *getPPCallbacks() const { return Callbacks; }
+ void setPPCallbacks(PPCallbacks *C) {
+ Callbacks = C;
+ }
+
+ /// getIdentifierInfo - Return information about the specified preprocessor
+ /// identifier token. The version of this method that takes two character
+ /// pointers is preferred unless the identifier is already available as a
+ /// string (this avoids allocation and copying of memory to construct an
+ /// std::string).
+ IdentifierInfo *getIdentifierInfo(const char *NameStart,
+ const char *NameEnd) {
+ return &Identifiers.get(NameStart, NameEnd);
+ }
+ IdentifierInfo *getIdentifierInfo(const char *NameStr) {
+ return getIdentifierInfo(NameStr, NameStr+strlen(NameStr));
+ }
+
+ /// AddPragmaHandler - Add the specified pragma handler to the preprocessor.
+ /// If 'Namespace' is non-null, then it is a token required to exist on the
+ /// pragma line before the pragma string starts, e.g. "STDC" or "GCC".
+ void AddPragmaHandler(const char *Namespace, PragmaHandler *Handler);
+
+ /// EnterSourceFile - Add a source file to the top of the include stack and
+ /// start lexing tokens from it instead of the current buffer. If isMainFile
+ /// is true, this is the main file for the translation unit.
+ void EnterSourceFile(unsigned CurFileID, const DirectoryLookup *Dir,
+ bool isMainFile = false);
+
+ /// EnterMacro - Add a Macro to the top of the include stack and start lexing
+ /// tokens from it instead of the current buffer. Args specifies the
+ /// tokens input to a function-like macro.
+ void EnterMacro(LexerToken &Identifier, MacroArgs *Args);
+
+ /// EnterTokenStream - Add a "macro" context to the top of the include stack,
+ /// which will cause the lexer to start returning the specified tokens. Note
+ /// that these tokens will be re-macro-expanded when/if expansion is enabled.
+ /// This method assumes that the specified stream of tokens has a permanent
+ /// owner somewhere, so they do not need to be copied.
+ void EnterTokenStream(const LexerToken *Toks, unsigned NumToks);
+
+ /// RemoveTopOfLexerStack - Pop the current lexer/macro exp off the top of the
+ /// lexer stack. This should only be used in situations where the current
+ /// state of the top-of-stack lexer is known.
+ void RemoveTopOfLexerStack();
+
+ /// Lex - To lex a token from the preprocessor, just pull a token from the
+ /// current lexer or macro object.
+ void Lex(LexerToken &Result) {
+ if (CurLexer)
+ CurLexer->Lex(Result);
+ else
+ CurMacroExpander->Lex(Result);
+ }
+
+ /// LexNonComment - Lex a token. If it's a comment, keep lexing until we get
+ /// something not a comment. This is useful in -E -C mode where comments
+ /// would foul up preprocessor directive handling.
+ void LexNonComment(LexerToken &Result) {
+ do
+ Lex(Result);
+ while (Result.getKind() == tok::comment);
+ }
+
+ /// LexUnexpandedToken - This is just like Lex, but this disables macro
+ /// expansion of identifier tokens.
+ void LexUnexpandedToken(LexerToken &Result) {
+ // Disable macro expansion.
+ bool OldVal = DisableMacroExpansion;
+ DisableMacroExpansion = true;
+ // Lex the token.
+ Lex(Result);
+
+ // Reenable it.
+ DisableMacroExpansion = OldVal;
+ }
+
+ /// Diag - Forwarding function for diagnostics. This emits a diagnostic at
+ /// the specified LexerToken's location, translating the token's start
+ /// position in the current buffer into a SourcePosition object for rendering.
+ void Diag(SourceLocation Loc, unsigned DiagID);
+ void Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg);
+ void Diag(const LexerToken &Tok, unsigned DiagID) {
+ Diag(Tok.getLocation(), DiagID);
+ }
+ void Diag(const LexerToken &Tok, unsigned DiagID, const std::string &Msg) {
+ Diag(Tok.getLocation(), DiagID, Msg);
+ }
+
+ /// getSpelling() - Return the 'spelling' of the Tok token. The spelling of a
+ /// token is the characters used to represent the token in the source file
+ /// after trigraph expansion and escaped-newline folding. In particular, this
+ /// wants to get the true, uncanonicalized, spelling of things like digraphs
+ /// UCNs, etc.
+ std::string getSpelling(const LexerToken &Tok) const;
+
+ /// getSpelling - This method is used to get the spelling of a token into a
+ /// preallocated buffer, instead of as an std::string. The caller is required
+ /// to allocate enough space for the token, which is guaranteed to be at least
+ /// Tok.getLength() bytes long. The length of the actual result is returned.
+ ///
+ /// Note that this method may do two possible things: it may either fill in
+ /// the buffer specified with characters, or it may *change the input pointer*
+ /// to point to a constant buffer with the data already in it (avoiding a
+ /// copy). The caller is not allowed to modify the returned buffer pointer
+ /// if an internal buffer is returned.
+ unsigned getSpelling(const LexerToken &Tok, const char *&Buffer) const;
+
+
+ /// CreateString - Plop the specified string into a scratch buffer and return
+ /// a location for it. If specified, the source location provides a source
+ /// location for the token.
+ SourceLocation CreateString(const char *Buf, unsigned Len,
+ SourceLocation SourceLoc = SourceLocation());
+
+ /// DumpToken - Print the token to stderr, used for debugging.
+ ///
+ void DumpToken(const LexerToken &Tok, bool DumpFlags = false) const;
+ void DumpMacro(const MacroInfo &MI) const;
+
+ /// IncrementPasteCounter - Increment the counters for the number of token
+ /// paste operations performed. If fast was specified, this is a 'fast paste'
+ /// case we handled.
+ ///
+ void IncrementPasteCounter(bool isFast) {
+ if (isFast)
+ ++NumFastTokenPaste;
+ else
+ ++NumTokenPaste;
+ }
+
+ void PrintStats();
+
+ //===--------------------------------------------------------------------===//
+ // Preprocessor callback methods. These are invoked by a lexer as various
+ // directives and events are found.
+
+ /// LookUpIdentifierInfo - Given a tok::identifier token, look up the
+ /// identifier information for the token and install it into the token.
+ IdentifierInfo *LookUpIdentifierInfo(LexerToken &Identifier,
+ const char *BufPtr = 0);
+
+ /// HandleIdentifier - This callback is invoked when the lexer reads an
+ /// identifier and has filled in the tokens IdentifierInfo member. This
+ /// callback potentially macro expands it or turns it into a named token (like
+ /// 'for').
+ void HandleIdentifier(LexerToken &Identifier);
+
+
+ /// HandleEndOfFile - This callback is invoked when the lexer hits the end of
+ /// the current file. This either returns the EOF token and returns true, or
+ /// pops a level off the include stack and returns false, at which point the
+ /// client should call lex again.
+ bool HandleEndOfFile(LexerToken &Result, bool isEndOfMacro = false);
+
+ /// HandleEndOfMacro - This callback is invoked when the lexer hits the end of
+ /// the current macro line. It returns true if Result is filled in with a
+ /// token, or false if Lex should be called again.
+ bool HandleEndOfMacro(LexerToken &Result);
+
+ /// HandleDirective - This callback is invoked when the lexer sees a # token
+ /// at the start of a line. This consumes the directive, modifies the
+ /// lexer/preprocessor state, and advances the lexer(s) so that the next token
+ /// read is the correct one.
+ void HandleDirective(LexerToken &Result);
+
+ /// CheckEndOfDirective - Ensure that the next token is a tok::eom token. If
+ /// not, emit a diagnostic and consume up until the eom.
+ void CheckEndOfDirective(const char *Directive);
+private:
+
+ /// DiscardUntilEndOfDirective - Read and discard all tokens remaining on the
+ /// current line until the tok::eom token is found.
+ void DiscardUntilEndOfDirective();
+
+ /// ReadMacroName - Lex and validate a macro name, which occurs after a
+ /// #define or #undef. This emits a diagnostic, sets the token kind to eom,
+ /// and discards the rest of the macro line if the macro name is invalid.
+ void ReadMacroName(LexerToken &MacroNameTok, char isDefineUndef = 0);
+
+ /// ReadMacroDefinitionArgList - The ( starting an argument list of a macro
+ /// definition has just been read. Lex the rest of the arguments and the
+ /// closing ), updating MI with what we learn. Return true if an error occurs
+ /// parsing the arg list.
+ bool ReadMacroDefinitionArgList(MacroInfo *MI);
+
+ /// SkipExcludedConditionalBlock - We just read a #if or related directive and
+ /// decided that the subsequent tokens are in the #if'd out portion of the
+ /// file. Lex the rest of the file, until we see an #endif. If
+ /// FoundNonSkipPortion is true, then we have already emitted code for part of
+ /// this #if directive, so #else/#elif blocks should never be entered. If
+ /// FoundElse is false, then #else directives are ok, if not, then we have
+ /// already seen one so a #else directive is a duplicate. When this returns,
+ /// the caller can lex the first valid token.
+ void SkipExcludedConditionalBlock(SourceLocation IfTokenLoc,
+ bool FoundNonSkipPortion, bool FoundElse);
+
+ /// EvaluateDirectiveExpression - Evaluate an integer constant expression that
+ /// may occur after a #if or #elif directive and return it as a bool. If the
+ /// expression is equivalent to "!defined(X)" return X in IfNDefMacro.
+ bool EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro);
+
+ /// RegisterBuiltinPragmas - Install the standard preprocessor pragmas:
+ /// #pragma GCC poison/system_header/dependency and #pragma once.
+ void RegisterBuiltinPragmas();
+
+ /// RegisterBuiltinMacros - Register builtin macros, such as __LINE__ with the
+ /// identifier table.
+ void RegisterBuiltinMacros();
+ IdentifierInfo *RegisterBuiltinMacro(const char *Name);
+
+ /// HandleMacroExpandedIdentifier - If an identifier token is read that is to
+ /// be expanded as a macro, handle it and return the next token as 'Tok'. If
+ /// the macro should not be expanded return true, otherwise return false.
+ bool HandleMacroExpandedIdentifier(LexerToken &Tok, MacroInfo *MI);
+
+ /// isNextPPTokenLParen - Determine whether the next preprocessor token to be
+ /// lexed is a '('. If so, consume the token and return true, if not, this
+ /// method should have no observable side-effect on the lexed tokens.
+ bool isNextPPTokenLParen();
+
+ /// ReadFunctionLikeMacroArgs - After reading "MACRO(", this method is
+ /// invoked to read all of the formal arguments specified for the macro
+ /// invocation. This returns null on error.
+ MacroArgs *ReadFunctionLikeMacroArgs(LexerToken &MacroName, MacroInfo *MI);
+
+ /// ExpandBuiltinMacro - If an identifier token is read that is to be expanded
+ /// as a builtin macro, handle it and return the next token as 'Tok'.
+ void ExpandBuiltinMacro(LexerToken &Tok);
+
+ /// Handle_Pragma - Read a _Pragma directive, slice it up, process it, then
+ /// return the first token after the directive. The _Pragma token has just
+ /// been read into 'Tok'.
+ void Handle_Pragma(LexerToken &Tok);
+
+
+ /// EnterSourceFileWithLexer - Add a lexer to the top of the include stack and
+ /// start lexing tokens from it instead of the current buffer.
+ void EnterSourceFileWithLexer(Lexer *TheLexer, const DirectoryLookup *Dir);
+
+ /// GetIncludeFilenameSpelling - Turn the specified lexer token into a fully
+ /// checked and spelled filename, e.g. as an operand of #include. This returns
+ /// true if the input filename was in <>'s or false if it were in ""'s. The
+ /// caller is expected to provide a buffer that is large enough to hold the
+ /// spelling of the filename, but is also expected to handle the case when
+ /// this method decides to use a different buffer.
+ bool GetIncludeFilenameSpelling(const LexerToken &FNTok,
+ const char *&BufStart, const char *&BufEnd);
+
+ /// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
+ /// return null on failure. isAngled indicates whether the file reference is
+ /// for system #include's or not (i.e. using <> instead of "").
+ const FileEntry *LookupFile(const char *FilenameStart,const char *FilenameEnd,
+ bool isAngled, const DirectoryLookup *FromDir,
+ const DirectoryLookup *&CurDir);
+
+ //===--------------------------------------------------------------------===//
+ /// Handle*Directive - implement the various preprocessor directives. These
+ /// should side-effect the current preprocessor object so that the next call
+ /// to Lex() will return the appropriate token next.
+
+ void HandleUserDiagnosticDirective(LexerToken &Tok, bool isWarning);
+ void HandleIdentSCCSDirective(LexerToken &Tok);
+
+ // File inclusion.
+ void HandleIncludeDirective(LexerToken &Tok,
+ const DirectoryLookup *LookupFrom = 0,
+ bool isImport = false);
+ void HandleIncludeNextDirective(LexerToken &Tok);
+ void HandleImportDirective(LexerToken &Tok);
+
+ // Macro handling.
+ void HandleDefineDirective(LexerToken &Tok, bool isTargetSpecific);
+ void HandleUndefDirective(LexerToken &Tok);
+ void HandleDefineOtherTargetDirective(LexerToken &Tok);
+ // HandleAssertDirective(LexerToken &Tok);
+ // HandleUnassertDirective(LexerToken &Tok);
+
+ // Conditional Inclusion.
+ void HandleIfdefDirective(LexerToken &Tok, bool isIfndef,
+ bool ReadAnyTokensBeforeDirective);
+ void HandleIfDirective(LexerToken &Tok, bool ReadAnyTokensBeforeDirective);
+ void HandleEndifDirective(LexerToken &Tok);
+ void HandleElseDirective(LexerToken &Tok);
+ void HandleElifDirective(LexerToken &Tok);
+
+ // Pragmas.
+ void HandlePragmaDirective();
+public:
+ void HandlePragmaOnce(LexerToken &OnceTok);
+ void HandlePragmaPoison(LexerToken &PoisonTok);
+ void HandlePragmaSystemHeader(LexerToken &SysHeaderTok);
+ void HandlePragmaDependency(LexerToken &DependencyTok);
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Lex/ScratchBuffer.h b/include/clang/Lex/ScratchBuffer.h
new file mode 100644
index 0000000..e2d62d1
--- /dev/null
+++ b/include/clang/Lex/ScratchBuffer.h
@@ -0,0 +1,50 @@
+//===--- ScratchBuffer.h - Scratch space for forming tokens -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ScratchBuffer interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SCRATCHBUFFER_H
+#define LLVM_CLANG_SCRATCHBUFFER_H
+
+namespace clang {
+ class SourceManager;
+ class SourceLocation;
+
+/// ScratchBuffer - This class exposes a simple interface for the dynamic
+/// construction of tokens. This is used for builtin macros (e.g. __LINE__) as
+/// well as token pasting, etc.
+class ScratchBuffer {
+ SourceManager &SourceMgr;
+ char *CurBuffer;
+ unsigned FileID;
+ unsigned BytesUsed;
+public:
+ ScratchBuffer(SourceManager &SM);
+
+ /// getToken - Splat the specified text into a temporary MemoryBuffer and
+ /// return a SourceLocation that refers to the token. The SourceLoc value
+ /// gives a virtual location that the token will appear to be from.
+ SourceLocation getToken(const char *Buf, unsigned Len,
+ SourceLocation SourceLoc);
+
+ /// getToken - Splat the specified text into a temporary MemoryBuffer and
+ /// return a SourceLocation that refers to the token. This is just like the
+ /// previous method, but returns a location that indicates the physloc of the
+ /// token.
+ SourceLocation getToken(const char *Buf, unsigned Len);
+
+private:
+ void AllocScratchBuffer(unsigned RequestLen);
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h
new file mode 100644
index 0000000..bd7fbe4
--- /dev/null
+++ b/include/clang/Parse/Action.h
@@ -0,0 +1,404 @@
+//===--- Action.h - Parser Action Interface ---------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the Action and EmptyAction interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PARSE_ACTION_H
+#define LLVM_CLANG_PARSE_ACTION_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/TokenKinds.h"
+
+namespace clang {
+ // Semantic.
+ class DeclSpec;
+ class Declarator;
+ class AttributeList;
+ // Parse.
+ class Scope;
+ class Action;
+ // Lex.
+ class IdentifierInfo;
+ class LexerToken;
+
+/// Action - As the parser reads the input file and recognizes the productions
+/// of the grammar, it invokes methods on this class to turn the parsed input
+/// into something useful: e.g. a parse tree.
+///
+/// The callback methods that this class provides are phrased as actions that
+/// the parser has just done or is about to do when the method is called. They
+/// are not requests that the actions module do the specified action.
+///
+/// All of the methods here are optional except isTypeName(), which must be
+/// specified in order for the parse to complete accurately. The EmptyAction
+/// class does this bare-minimum of tracking to implement this functionality.
+class Action {
+public:
+ /// Out-of-line virtual destructor to provide home for this class.
+ virtual ~Action();
+
+ // Types - Though these don't actually enforce strong typing, they document
+ // what types are required to be identical for the actions.
+ typedef void ExprTy;
+ typedef void StmtTy;
+ typedef void DeclTy;
+ typedef void TypeTy;
+ typedef void AttrTy;
+
+ /// ActionResult - This structure is used while parsing/acting on expressions,
+ /// stmts, etc. It encapsulates both the object returned by the action, plus
+ /// a sense of whether or not it is valid.
+ template<unsigned UID>
+ struct ActionResult {
+ void *Val;
+ bool isInvalid;
+
+ ActionResult(bool Invalid = false) : Val(0), isInvalid(Invalid) {}
+ template<typename ActualExprTy>
+ ActionResult(ActualExprTy *val) : Val(val), isInvalid(false) {}
+
+ const ActionResult &operator=(void *RHS) {
+ Val = RHS;
+ isInvalid = false;
+ return *this;
+ }
+ };
+
+ /// Expr/Stmt/TypeResult - Provide a unique type to wrap ExprTy/StmtTy/TypeTy,
+ /// providing strong typing and allowing for failure.
+ typedef ActionResult<0> ExprResult;
+ typedef ActionResult<1> StmtResult;
+ typedef ActionResult<2> TypeResult;
+
+ //===--------------------------------------------------------------------===//
+ // Declaration Tracking Callbacks.
+ //===--------------------------------------------------------------------===//
+
+ /// isTypeName - Return non-null if the specified identifier is a typedef name
+ /// in the current scope.
+ virtual DeclTy *isTypeName(const IdentifierInfo &II, Scope *S) const = 0;
+
+ /// ParseDeclarator - This callback is invoked when a declarator is parsed and
+ /// 'Init' specifies the initializer if any. This is for things like:
+ /// "int X = 4" or "typedef int foo".
+ ///
+ /// LastInGroup is non-null for cases where one declspec has multiple
+ /// declarators on it. For example in 'int A, B', ParseDeclarator will be
+ /// called with LastInGroup=A when invoked for B.
+ virtual DeclTy *ParseDeclarator(Scope *S, Declarator &D,
+ ExprTy *Init, DeclTy *LastInGroup) {
+ return 0;
+ }
+
+ /// FinalizeDeclaratorGroup - After a sequence of declarators are parsed, this
+ /// gives the actions implementation a chance to process the group as a whole.
+ virtual DeclTy *FinalizeDeclaratorGroup(Scope *S, DeclTy *Group) {
+ return Group;
+ }
+
+ /// ParseStartOfFunctionDef - This is called at the start of a function
+ /// definition, instead of calling ParseDeclarator. The Declarator includes
+ /// information about formal arguments that are part of this function.
+ virtual DeclTy *ParseStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) {
+ // Default to ParseDeclarator.
+ return ParseDeclarator(FnBodyScope, D, 0, 0);
+ }
+
+ /// ParseFunctionDefBody - This is called when a function body has completed
+ /// parsing. Decl is the DeclTy returned by ParseStartOfFunctionDef.
+ virtual DeclTy *ParseFunctionDefBody(DeclTy *Decl, StmtTy *Body) {
+ return Decl;
+ }
+
+
+ /// PopScope - This callback is called immediately before the specified scope
+ /// is popped and deleted.
+ virtual void PopScope(SourceLocation Loc, Scope *S) {}
+
+ /// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
+ /// no declarator (e.g. "struct foo;") is parsed.
+ virtual DeclTy *ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS) {
+ return 0;
+ }
+
+ virtual DeclTy *ParsedObjcClassDeclaration(Scope *S,
+ IdentifierInfo **IdentList,
+ unsigned NumElts) {
+ return 0;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Type Parsing Callbacks.
+ //===--------------------------------------------------------------------===//
+
+ virtual TypeResult ParseTypeName(Scope *S, Declarator &D) {
+ return 0;
+ }
+
+ virtual TypeResult ParseParamDeclaratorType(Scope *S, Declarator &D) {
+ return 0;
+ }
+
+ enum TagKind {
+ TK_Reference, // Reference to a tag: 'struct foo *X;'
+ TK_Declaration, // Fwd decl of a tag: 'struct foo;'
+ TK_Definition // Definition of a tag: 'struct foo { int X; } Y;'
+ };
+ virtual DeclTy *ParseTag(Scope *S, unsigned TagType, TagKind TK,
+ SourceLocation KWLoc, IdentifierInfo *Name,
+ SourceLocation NameLoc, AttributeList *Attr) {
+ // TagType is an instance of DeclSpec::TST, indicating what kind of tag this
+ // is (struct/union/enum/class).
+ return 0;
+ }
+
+ virtual DeclTy *ParseField(Scope *S, DeclTy *TagDecl,SourceLocation DeclStart,
+ Declarator &D, ExprTy *BitfieldWidth) {
+ return 0;
+ }
+ virtual void ParseRecordBody(SourceLocation RecLoc, DeclTy *TagDecl,
+ DeclTy **Fields, unsigned NumFields) {}
+
+ virtual DeclTy *ParseEnumConstant(Scope *S, DeclTy *EnumDecl,
+ DeclTy *LastEnumConstant,
+ SourceLocation IdLoc, IdentifierInfo *Id,
+ SourceLocation EqualLoc, ExprTy *Val) {
+ return 0;
+ }
+ virtual void ParseEnumBody(SourceLocation EnumLoc, DeclTy *EnumDecl,
+ DeclTy **Elements, unsigned NumElements) {}
+
+ //===--------------------------------------------------------------------===//
+ // Statement Parsing Callbacks.
+ //===--------------------------------------------------------------------===//
+
+ virtual StmtResult ParseNullStmt(SourceLocation SemiLoc) {
+ return 0;
+ }
+
+ virtual StmtResult ParseCompoundStmt(SourceLocation L, SourceLocation R,
+ StmtTy **Elts, unsigned NumElts) {
+ return 0;
+ }
+ virtual StmtResult ParseDeclStmt(DeclTy *Decl) {
+ return 0;
+ }
+
+ virtual StmtResult ParseExprStmt(ExprTy *Expr) {
+ return StmtResult(Expr);
+ }
+
+ /// ParseCaseStmt - Note that this handles the GNU 'case 1 ... 4' extension,
+ /// which can specify an RHS value.
+ virtual StmtResult ParseCaseStmt(SourceLocation CaseLoc, ExprTy *LHSVal,
+ SourceLocation DotDotDotLoc, ExprTy *RHSVal,
+ SourceLocation ColonLoc, StmtTy *SubStmt) {
+ return 0;
+ }
+ virtual StmtResult ParseDefaultStmt(SourceLocation DefaultLoc,
+ SourceLocation ColonLoc, StmtTy *SubStmt){
+ return 0;
+ }
+
+ virtual StmtResult ParseLabelStmt(SourceLocation IdentLoc, IdentifierInfo *II,
+ SourceLocation ColonLoc, StmtTy *SubStmt) {
+ return 0;
+ }
+
+ virtual StmtResult ParseIfStmt(SourceLocation IfLoc, ExprTy *CondVal,
+ StmtTy *ThenVal, SourceLocation ElseLoc,
+ StmtTy *ElseVal) {
+ return 0;
+ }
+
+ virtual StmtResult ParseSwitchStmt(SourceLocation SwitchLoc, ExprTy *Cond,
+ StmtTy *Body) {
+ return 0;
+ }
+ virtual StmtResult ParseWhileStmt(SourceLocation WhileLoc, ExprTy *Cond,
+ StmtTy *Body) {
+ return 0;
+ }
+ virtual StmtResult ParseDoStmt(SourceLocation DoLoc, StmtTy *Body,
+ SourceLocation WhileLoc, ExprTy *Cond) {
+ return 0;
+ }
+ virtual StmtResult ParseForStmt(SourceLocation ForLoc,
+ SourceLocation LParenLoc,
+ StmtTy *First, ExprTy *Second, ExprTy *Third,
+ SourceLocation RParenLoc, StmtTy *Body) {
+ return 0;
+ }
+ virtual StmtResult ParseGotoStmt(SourceLocation GotoLoc,
+ SourceLocation LabelLoc,
+ IdentifierInfo *LabelII) {
+ return 0;
+ }
+ virtual StmtResult ParseIndirectGotoStmt(SourceLocation GotoLoc,
+ SourceLocation StarLoc,
+ ExprTy *DestExp) {
+ return 0;
+ }
+ virtual StmtResult ParseContinueStmt(SourceLocation ContinueLoc,
+ Scope *CurScope) {
+ return 0;
+ }
+ virtual StmtResult ParseBreakStmt(SourceLocation GotoLoc, Scope *CurScope) {
+ return 0;
+ }
+ virtual StmtResult ParseReturnStmt(SourceLocation ReturnLoc,
+ ExprTy *RetValExp) {
+ return 0;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Expression Parsing Callbacks.
+ //===--------------------------------------------------------------------===//
+
+ // Primary Expressions.
+
+ /// ParseIdentifierExpr - Parse an identifier in expression context.
+ /// 'HasTrailingLParen' indicates whether or not the identifier has a '('
+ /// token immediately after it.
+ virtual ExprResult ParseIdentifierExpr(Scope *S, SourceLocation Loc,
+ IdentifierInfo &II,
+ bool HasTrailingLParen) {
+ return 0;
+ }
+
+ virtual ExprResult ParseSimplePrimaryExpr(SourceLocation Loc,
+ tok::TokenKind Kind) {
+ return 0;
+ }
+ virtual ExprResult ParseCharacterConstant(const LexerToken &) { return 0; }
+ virtual ExprResult ParseNumericConstant(const LexerToken &) { return 0; }
+
+ /// ParseStringLiteral - The specified tokens were lexed as pasted string
+ /// fragments (e.g. "foo" "bar" L"baz").
+ virtual ExprResult ParseStringLiteral(const LexerToken *Toks, unsigned NumToks) {
+ return 0;
+ }
+
+ virtual ExprResult ParseParenExpr(SourceLocation L, SourceLocation R,
+ ExprTy *Val) {
+ return Val; // Default impl returns operand.
+ }
+
+ // Postfix Expressions.
+ virtual ExprResult ParsePostfixUnaryOp(SourceLocation OpLoc,
+ tok::TokenKind Kind, ExprTy *Input) {
+ return 0;
+ }
+ virtual ExprResult ParseArraySubscriptExpr(ExprTy *Base, SourceLocation LLoc,
+ ExprTy *Idx, SourceLocation RLoc) {
+ return 0;
+ }
+ virtual ExprResult ParseMemberReferenceExpr(ExprTy *Base,SourceLocation OpLoc,
+ tok::TokenKind OpKind,
+ SourceLocation MemberLoc,
+ IdentifierInfo &Member) {
+ return 0;
+ }
+
+ /// ParseCallExpr - Handle a call to Fn with the specified array of arguments.
+ /// This provides the location of the left/right parens and a list of comma
+ /// locations. There are guaranteed to be one fewer commas than arguments,
+ /// unless there are zero arguments.
+ virtual ExprResult ParseCallExpr(ExprTy *Fn, SourceLocation LParenLoc,
+ ExprTy **Args, unsigned NumArgs,
+ SourceLocation *CommaLocs,
+ SourceLocation RParenLoc) {
+ return 0;
+ }
+
+ // Unary Operators. 'Tok' is the token for the operator.
+ virtual ExprResult ParseUnaryOp(SourceLocation OpLoc, tok::TokenKind Op,
+ ExprTy *Input) {
+ return 0;
+ }
+ virtual ExprResult
+ ParseSizeOfAlignOfTypeExpr(SourceLocation OpLoc, bool isSizeof,
+ SourceLocation LParenLoc, TypeTy *Ty,
+ SourceLocation RParenLoc) {
+ return 0;
+ }
+
+ virtual ExprResult ParseCastExpr(SourceLocation LParenLoc, TypeTy *Ty,
+ SourceLocation RParenLoc, ExprTy *Op) {
+ return 0;
+ }
+
+ virtual ExprResult ParseBinOp(SourceLocation TokLoc, tok::TokenKind Kind,
+ ExprTy *LHS, ExprTy *RHS) {
+ return 0;
+ }
+
+ /// ParseConditionalOp - Parse a ?: operation. Note that 'LHS' may be null
+ /// in the case of a the GNU conditional expr extension.
+ virtual ExprResult ParseConditionalOp(SourceLocation QuestionLoc,
+ SourceLocation ColonLoc,
+ ExprTy *Cond, ExprTy *LHS, ExprTy *RHS){
+ return 0;
+ }
+
+ virtual ExprResult ParseAddrLabel(SourceLocation OpLoc, SourceLocation LabLoc,
+ IdentifierInfo *LabelII) { // "&&foo"
+ return 0;
+ }
+
+
+ /// ParseCXXCasts - Parse {dynamic,static,reinterpret,const}_cast's.
+ virtual ExprResult ParseCXXCasts(SourceLocation OpLoc, tok::TokenKind Kind,
+ SourceLocation LAngleBracketLoc, TypeTy *Ty,
+ SourceLocation RAngleBracketLoc,
+ SourceLocation LParenLoc, ExprTy *Op,
+ SourceLocation RParenLoc) {
+ return 0;
+ }
+
+ /// ParseCXXBoolLiteral - Parse {true,false} literals.
+ virtual ExprResult ParseCXXBoolLiteral(SourceLocation OpLoc,
+ tok::TokenKind Kind) {
+ return 0;
+ }
+};
+
+/// MinimalAction - Minimal actions are used by light-weight clients of the
+/// parser that do not need name resolution or significant semantic analysis to
+/// be performed. The actions implemented here are in the form of unresolved
+/// identifiers. By using a simpler interface than the SemanticAction class,
+/// the parser doesn't have to build complex data structures and thus runs more
+/// quickly.
+class MinimalAction : public Action {
+public:
+ /// isTypeName - This looks at the IdentifierInfo::FETokenInfo field to
+ /// determine whether the name is a typedef or not in this scope.
+ virtual DeclTy *isTypeName(const IdentifierInfo &II, Scope *S) const;
+
+ /// ParseDeclarator - If this is a typedef declarator, we modify the
+ /// IdentifierInfo::FETokenInfo field to keep track of this fact, until S is
+ /// popped.
+ virtual DeclTy *ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init,
+ DeclTy *LastInGroup);
+
+ /// PopScope - When a scope is popped, if any typedefs are now out-of-scope,
+ /// they are removed from the IdentifierInfo::FETokenInfo field.
+ virtual void PopScope(SourceLocation Loc, Scope *S);
+
+ virtual DeclTy *ParsedObjcClassDeclaration(Scope *S,
+ IdentifierInfo **IdentList,
+ unsigned NumElts);
+
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Parse/AttributeList.h b/include/clang/Parse/AttributeList.h
new file mode 100644
index 0000000..8bde7d0
--- /dev/null
+++ b/include/clang/Parse/AttributeList.h
@@ -0,0 +1,86 @@
+//===--- AttributeList.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Steve Naroff and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the AttributeList class interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ATTRLIST_H
+#define LLVM_CLANG_ATTRLIST_H
+
+#include "clang/Parse/Action.h"
+#include <cassert>
+
+namespace clang {
+
+/// AttributeList - Represents GCC's __attribute__ declaration. There are
+/// 4 forms of this construct...they are:
+///
+/// 1: __attribute__(( const )). ParmName/Args/NumArgs will all be unused.
+/// 2: __attribute__(( mode(byte) )). ParmName used, Args/NumArgs unused.
+/// 3: __attribute__(( format(printf, 1, 2) )). ParmName/Args/NumArgs all used.
+/// 4: __attribute__(( aligned(16) )). ParmName is unused, Args/Num used.
+///
+class AttributeList {
+ IdentifierInfo *AttrName;
+ SourceLocation AttrLoc;
+ IdentifierInfo *ParmName;
+ SourceLocation ParmLoc;
+ Action::ExprTy **Args;
+ unsigned NumArgs;
+ AttributeList *Next;
+public:
+ AttributeList(IdentifierInfo *AttrName, SourceLocation AttrLoc,
+ IdentifierInfo *ParmName, SourceLocation ParmLoc,
+ Action::ExprTy **args, unsigned numargs, AttributeList *Next);
+ ~AttributeList() {
+ if (Args) {
+ // FIXME: before we delete the vector, we need to make sure the Expr's
+ // have been deleted. Since Action::ExprTy is "void", we are dependent
+ // on the actions module for actually freeing the memory. The specific
+ // hooks are ParseDeclarator, ParseTypeName, ParseParamDeclaratorType,
+ // ParseField, ParseTag. Once these routines have freed the expression,
+ // they should zero out the Args slot (to indicate the memory has been
+ // freed). If any element of the vector is non-null, we should assert.
+ delete [] Args;
+ }
+ if (Next)
+ delete Next;
+ }
+
+ IdentifierInfo *getAttributeName() const { return AttrName; }
+ SourceLocation getAttributeLoc() const { return AttrLoc; }
+ IdentifierInfo *getParameterName() const { return ParmName; }
+
+ AttributeList *getNext() const { return Next; }
+ void setNext(AttributeList *N) { Next = N; }
+
+ void addAttributeList(AttributeList *alist) {
+ assert((alist != 0) && "addAttributeList(): alist is null");
+ AttributeList *next = this, *prev;
+ do {
+ prev = next;
+ next = next->getNext();
+ } while (next);
+ prev->setNext(alist);
+ }
+
+ /// getNumArgs - Return the number of actual arguments to this attribute.
+ unsigned getNumArgs() const { return NumArgs; }
+
+ /// getArg - Return the specified argument.
+ Action::ExprTy *getArg(unsigned Arg) const {
+ assert(Arg < NumArgs && "Arg access out of range!");
+ return Args[Arg];
+ }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Parse/DeclSpec.h b/include/clang/Parse/DeclSpec.h
new file mode 100644
index 0000000..95be993
--- /dev/null
+++ b/include/clang/Parse/DeclSpec.h
@@ -0,0 +1,552 @@
+//===--- SemaDeclSpec.h - Declaration Specifier Semantic Analys -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines interfaces used for Declaration Specifiers and Declarators.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PARSE_SEMADECLSPEC_H
+#define LLVM_CLANG_PARSE_SEMADECLSPEC_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Parse/Action.h"
+#include "clang/Parse/AttributeList.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+ class LangOptions;
+ class IdentifierInfo;
+
+/// DeclSpec - This class captures information about "declaration specifiers",
+/// which encompases storage-class-specifiers, type-specifiers, type-qualifiers,
+/// and function-specifiers.
+class DeclSpec {
+public:
+ // storage-class-specifier
+ enum SCS {
+ SCS_unspecified,
+ SCS_typedef,
+ SCS_extern,
+ SCS_static,
+ SCS_auto,
+ SCS_register
+ };
+
+ // type-specifier
+ enum TSW {
+ TSW_unspecified,
+ TSW_short,
+ TSW_long,
+ TSW_longlong
+ };
+
+ enum TSC {
+ TSC_unspecified,
+ TSC_imaginary,
+ TSC_complex
+ };
+
+ enum TSS {
+ TSS_unspecified,
+ TSS_signed,
+ TSS_unsigned
+ };
+
+ enum TST {
+ TST_unspecified,
+ TST_void,
+ TST_char,
+ TST_int,
+ TST_float,
+ TST_double,
+ TST_bool, // _Bool
+ TST_decimal32, // _Decimal32
+ TST_decimal64, // _Decimal64
+ TST_decimal128, // _Decimal128
+ TST_enum,
+ TST_union,
+ TST_struct,
+ TST_typedef
+ };
+
+ // type-qualifiers
+ enum TQ { // NOTE: These flags must be kept in sync with QualType::TQ.
+ TQ_unspecified = 0,
+ TQ_const = 1,
+ TQ_restrict = 2,
+ TQ_volatile = 4
+ };
+
+ /// ParsedSpecifiers - Flags to query which specifiers were applied. This is
+ /// returned by getParsedSpecifiers.
+ enum ParsedSpecifiers {
+ PQ_None = 0,
+ PQ_StorageClassSpecifier = 1,
+ PQ_TypeSpecifier = 2,
+ PQ_TypeQualifier = 4,
+ PQ_FunctionSpecifier = 8
+ };
+
+private:
+
+ // storage-class-specifier
+ SCS StorageClassSpec : 3;
+ bool SCS_thread_specified : 1;
+
+ // type-specifier
+ TSW TypeSpecWidth : 2;
+ TSC TypeSpecComplex : 2;
+ TSS TypeSpecSign : 2;
+ TST TypeSpecType : 4;
+
+ // type-qualifiers
+ unsigned TypeQualifiers : 3; // Bitwise OR of TQ.
+
+ // function-specifier
+ bool FS_inline_specified : 1;
+
+ /// TypeRep - This contains action-specific information about a specific TST.
+ /// For example, for a typedef or struct, it might contain the declaration for
+ /// these.
+ void *TypeRep;
+
+ // attributes.
+ AttributeList *AttrList;
+
+ // SourceLocation info. These are null if the item wasn't specified or if
+ // the setting was synthesized.
+ SourceLocation StorageClassSpecLoc, SCS_threadLoc;
+ SourceLocation TSWLoc, TSCLoc, TSSLoc, TSTLoc;
+ SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc;
+ SourceLocation FS_inlineLoc;
+public:
+
+ DeclSpec()
+ : StorageClassSpec(SCS_unspecified),
+ SCS_thread_specified(false),
+ TypeSpecWidth(TSW_unspecified),
+ TypeSpecComplex(TSC_unspecified),
+ TypeSpecSign(TSS_unspecified),
+ TypeSpecType(TST_unspecified),
+ TypeQualifiers(TSS_unspecified),
+ FS_inline_specified(false),
+ TypeRep(0),
+ AttrList(0) {
+ }
+ ~DeclSpec() {
+ delete AttrList;
+ }
+ // storage-class-specifier
+ SCS getStorageClassSpec() const { return StorageClassSpec; }
+ bool isThreadSpecified() const { return SCS_thread_specified; }
+
+ SourceLocation getStorageClassSpecLoc() const { return StorageClassSpecLoc; }
+ SourceLocation getThreadSpecLoc() const { return SCS_threadLoc; }
+
+
+ void ClearStorageClassSpecs() {
+ StorageClassSpec = DeclSpec::SCS_unspecified;
+ SCS_thread_specified = false;
+ StorageClassSpecLoc = SourceLocation();
+ SCS_threadLoc = SourceLocation();
+ }
+
+ // type-specifier
+ TSW getTypeSpecWidth() const { return TypeSpecWidth; }
+ TSC getTypeSpecComplex() const { return TypeSpecComplex; }
+ TSS getTypeSpecSign() const { return TypeSpecSign; }
+ TST getTypeSpecType() const { return TypeSpecType; }
+ void *getTypeRep() const { return TypeRep; }
+
+ SourceLocation getTypeSpecWidthLoc() const { return TSWLoc; }
+ SourceLocation getTypeSpecComplexLoc() const { return TSCLoc; }
+ SourceLocation getTypeSpecSignLoc() const { return TSSLoc; }
+ SourceLocation getTypeSpecTypeLoc() const { return TSTLoc; }
+
+ /// getSpecifierName - Turn a type-specifier-type into a string like "_Bool"
+ /// or "union".
+ static const char *getSpecifierName(DeclSpec::TST T);
+ static const char *getSpecifierName(DeclSpec::SCS S);
+
+ // type-qualifiers
+
+ /// getTypeQualifiers - Return a set of TQs.
+ unsigned getTypeQualifiers() const { return TypeQualifiers; }
+ SourceLocation getConstSpecLoc() const { return TQ_constLoc; }
+ SourceLocation getRestrictSpecLoc() const { return TQ_restrictLoc; }
+ SourceLocation getVolatileSpecLoc() const { return TQ_volatileLoc; }
+
+
+ // function-specifier
+ bool isInlineSpecified() const { return FS_inline_specified; }
+ SourceLocation getInlineSpecLoc() const { return FS_inlineLoc; }
+ void ClearFunctionSpecs() {
+ FS_inline_specified = false;
+ FS_inlineLoc = SourceLocation();
+ }
+
+ /// hasTypeSpecifier - Return true if any type-specifier has been found.
+ bool hasTypeSpecifier() const {
+ return getTypeSpecType() != DeclSpec::TST_unspecified ||
+ getTypeSpecWidth() != DeclSpec::TSW_unspecified ||
+ getTypeSpecComplex() != DeclSpec::TSC_unspecified ||
+ getTypeSpecSign() != DeclSpec::TSS_unspecified;
+ }
+
+
+ /// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this
+ /// DeclSpec includes.
+ ///
+ unsigned getParsedSpecifiers() const;
+
+ /// These methods set the specified attribute of the DeclSpec, but return true
+ /// and ignore the request if invalid (e.g. "extern" then "auto" is
+ /// specified). The name of the previous specifier is returned in prevspec.
+ bool SetStorageClassSpec(SCS S, SourceLocation Loc, const char *&PrevSpec);
+ bool SetStorageClassSpecThread(SourceLocation Loc, const char *&PrevSpec);
+ bool SetTypeSpecWidth(TSW W, SourceLocation Loc, const char *&PrevSpec);
+ bool SetTypeSpecComplex(TSC C, SourceLocation Loc, const char *&PrevSpec);
+ bool SetTypeSpecSign(TSS S, SourceLocation Loc, const char *&PrevSpec);
+ bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec,
+ void *TypeRep = 0);
+
+ bool SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,
+ const LangOptions &Lang);
+
+ bool SetFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec);
+
+ /// AddAttributes - contatenates two attribute lists.
+ /// The GCC attribute syntax allows for the following:
+ ///
+ /// short __attribute__(( unused, deprecated ))
+ /// int __attribute__(( may_alias, aligned(16) )) var;
+ ///
+ /// This declares 4 attributes using 2 lists. The following syntax is
+ /// also allowed and equivalent to the previous declaration.
+ ///
+ /// short __attribute__((unused)) __attribute__((deprecated))
+ /// int __attribute__((may_alias)) __attribute__((aligned(16))) var;
+ ///
+ void AddAttributes(AttributeList *alist) {
+ if (!alist)
+ return; // we parsed __attribute__(()) or had a syntax error
+
+ if (AttrList)
+ alist->addAttributeList(AttrList);
+ AttrList = alist;
+ }
+ AttributeList *getAttributes() const { return AttrList; }
+
+ /// Finish - This does final analysis of the declspec, issuing diagnostics for
+ /// things like "_Imaginary" (lacking an FP type). After calling this method,
+ /// DeclSpec is guaranteed self-consistent, even if an error occurred.
+ void Finish(Diagnostic &D, const LangOptions &Lang);
+
+private:
+ void Diag(Diagnostic &D, SourceLocation Loc, unsigned DiagID) {
+ D.Report(Loc, DiagID);
+ }
+ void Diag(Diagnostic &D, SourceLocation Loc, unsigned DiagID,
+ const std::string &info) {
+ D.Report(Loc, DiagID, &info, 1);
+ }
+};
+
+
+/// DeclaratorChunk - One instance of this struct is used for each type in a
+/// declarator that is parsed.
+///
+/// This is intended to be a small value object.
+struct DeclaratorChunk {
+ enum {
+ Pointer, Reference, Array, Function
+ } Kind;
+
+ /// Loc - The place where this type was defined.
+ SourceLocation Loc;
+
+ struct PointerTypeInfo {
+ /// The type qualifiers: const/volatile/restrict.
+ unsigned TypeQuals : 3;
+ void destroy() {}
+ };
+
+ struct ReferenceTypeInfo {
+ /// The type qualifier: restrict. [GNU] C++ extension
+ bool HasRestrict;
+ void destroy() {}
+ };
+
+ struct ArrayTypeInfo {
+ /// The type qualifiers for the array: const/volatile/restrict.
+ unsigned TypeQuals : 3;
+
+ /// True if this dimension included the 'static' keyword.
+ bool hasStatic : 1;
+
+ /// True if this dimension was [*]. In this case, NumElts is null.
+ bool isStar : 1;
+
+ /// This is the size of the array, or null if [] or [*] was specified.
+ /// Since the parser is multi-purpose, and we don't want to impose a root
+ /// expression class on all clients, NumElts is untyped.
+ Action::ExprTy *NumElts;
+ void destroy() {}
+ };
+
+ /// ParamInfo - An array of paraminfo objects is allocated whenever a function
+ /// declarator is parsed. There are two interesting styles of arguments here:
+ /// K&R-style identifier lists and parameter type lists. K&R-style identifier
+ /// lists will have information about the identifier, but no type information.
+ /// Parameter type lists will have type info (if the actions module provides
+ /// it), but may have null identifier info: e.g. for 'void foo(int X, int)'.
+ struct ParamInfo {
+ IdentifierInfo *Ident;
+ SourceLocation IdentLoc;
+ Action::TypeTy *TypeInfo;
+ // FIXME: this also needs an attribute list.
+ ParamInfo() {}
+ ParamInfo(IdentifierInfo *ident, SourceLocation iloc, Action::TypeTy *typ)
+ : Ident(ident), IdentLoc(iloc), TypeInfo(typ) {
+ }
+ };
+
+ struct FunctionTypeInfo {
+ /// hasPrototype - This is true if the function had at least one typed
+ /// argument. If the function is () or (a,b,c), then it has no prototype,
+ /// and is treated as a K&R-style function.
+ bool hasPrototype : 1;
+
+ /// isVariadic - If this function has a prototype, and if that proto ends
+ /// with ',...)', this is true.
+ bool isVariadic : 1;
+
+ /// NumArgs - This is the number of formal arguments provided for the
+ /// declarator.
+ unsigned NumArgs;
+
+ /// ArgInfo - This is a pointer to a new[]'d array of ParamInfo objects that
+ /// describe the arguments for this function declarator. This is null if
+ /// there are no arguments specified.
+ ParamInfo *ArgInfo;
+
+ void destroy() {
+ delete[] ArgInfo;
+ }
+ };
+
+ union {
+ PointerTypeInfo Ptr;
+ ReferenceTypeInfo Ref;
+ ArrayTypeInfo Arr;
+ FunctionTypeInfo Fun;
+ };
+
+
+ /// getPointer - Return a DeclaratorChunk for a pointer.
+ ///
+ static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc) {
+ DeclaratorChunk I;
+ I.Kind = Pointer;
+ I.Loc = Loc;
+ I.Ptr.TypeQuals = TypeQuals;
+ return I;
+ }
+
+ /// getReference - Return a DeclaratorChunk for a reference.
+ ///
+ static DeclaratorChunk getReference(unsigned TypeQuals, SourceLocation Loc) {
+ DeclaratorChunk I;
+ I.Kind = Reference;
+ I.Loc = Loc;
+ I.Ref.HasRestrict = (TypeQuals & DeclSpec::TQ_restrict) != 0;
+ return I;
+ }
+
+ /// getArray - Return a DeclaratorChunk for an array.
+ ///
+ static DeclaratorChunk getArray(unsigned TypeQuals, bool isStatic,
+ bool isStar, void *NumElts,
+ SourceLocation Loc) {
+ DeclaratorChunk I;
+ I.Kind = Array;
+ I.Loc = Loc;
+ I.Arr.TypeQuals = TypeQuals;
+ I.Arr.hasStatic = isStatic;
+ I.Arr.isStar = isStar;
+ I.Arr.NumElts = NumElts;
+ return I;
+ }
+
+ /// getFunction - Return a DeclaratorChunk for a function.
+ static DeclaratorChunk getFunction(bool hasProto, bool isVariadic,
+ ParamInfo *ArgInfo, unsigned NumArgs,
+ SourceLocation Loc) {
+ DeclaratorChunk I;
+ I.Kind = Function;
+ I.Loc = Loc;
+ I.Fun.hasPrototype = hasProto;
+ I.Fun.isVariadic = isVariadic;
+ I.Fun.NumArgs = NumArgs;
+ I.Fun.ArgInfo = 0;
+
+ // new[] an argument array if needed.
+ if (NumArgs) {
+ I.Fun.ArgInfo = new DeclaratorChunk::ParamInfo[NumArgs];
+ memcpy(I.Fun.ArgInfo, ArgInfo, sizeof(ArgInfo[0])*NumArgs);
+ }
+ return I;
+ }
+};
+
+
+/// Declarator - Information about one declarator, including the parsed type
+/// information and the identifier. When the declarator is fully formed, this
+/// is turned into the appropriate Decl object.
+///
+/// Declarators come in two types: normal declarators and abstract declarators.
+/// Abstract declarators are used when parsing types, and don't have an
+/// identifier. Normal declarators do have ID's.
+///
+/// This is NOT intended to be a small value object: this should be a transient
+/// object that lives on the stack.
+class Declarator {
+ const DeclSpec &DS;
+ IdentifierInfo *Identifier;
+ SourceLocation IdentifierLoc;
+
+public:
+ enum TheContext {
+ FileContext, // File scope declaration.
+ PrototypeContext, // Within a function prototype.
+ KNRTypeListContext, // K&R type definition list for formals.
+ TypeNameContext, // Abstract declarator for types.
+ MemberContext, // Struct/Union field.
+ BlockContext, // Declaration within a block in a function.
+ ForContext // Declaration within first part of a for loop.
+ };
+private:
+ /// Context - Where we are parsing this declarator.
+ ///
+ TheContext Context;
+
+ /// DeclTypeInfo - This holds each type that the declarator includes as it is
+ /// parsed. This is pushed from the identifier out, which means that element
+ /// #0 will be the most closely bound to the identifier, and
+ /// DeclTypeInfo.back() will be the least closely bound.
+ llvm::SmallVector<DeclaratorChunk, 8> DeclTypeInfo;
+
+ // attributes.
+ AttributeList *AttrList;
+public:
+ Declarator(const DeclSpec &ds, TheContext C)
+ : DS(ds), Identifier(0), Context(C), AttrList(0) {
+ }
+
+ ~Declarator() {
+ clear();
+ }
+
+ /// getDeclSpec - Return the declaration-specifier that this declarator was
+ /// declared with.
+ const DeclSpec &getDeclSpec() const { return DS; }
+
+ TheContext getContext() const { return Context; }
+
+ /// clear - Reset the contents of this Declarator.
+ void clear() {
+ Identifier = 0;
+ IdentifierLoc = SourceLocation();
+
+ for (unsigned i = 0, e = DeclTypeInfo.size(); i != e; ++i) {
+ if (DeclTypeInfo[i].Kind == DeclaratorChunk::Function)
+ DeclTypeInfo[i].Fun.destroy();
+ else if (DeclTypeInfo[i].Kind == DeclaratorChunk::Pointer)
+ DeclTypeInfo[i].Ptr.destroy();
+ else if (DeclTypeInfo[i].Kind == DeclaratorChunk::Reference)
+ DeclTypeInfo[i].Ref.destroy();
+ else if (DeclTypeInfo[i].Kind == DeclaratorChunk::Array)
+ DeclTypeInfo[i].Arr.destroy();
+ else
+ assert(0 && "Unknown decl type!");
+ }
+ DeclTypeInfo.clear();
+ delete AttrList;
+ }
+
+ /// mayOmitIdentifier - Return true if the identifier is either optional or
+ /// not allowed. This is true for typenames and prototypes.
+ bool mayOmitIdentifier() const {
+ return Context == TypeNameContext || Context == PrototypeContext;
+ }
+
+ /// mayHaveIdentifier - Return true if the identifier is either optional or
+ /// required. This is true for normal declarators and prototypes, but not
+ /// typenames.
+ bool mayHaveIdentifier() const {
+ return Context != TypeNameContext;
+ }
+
+ /// isPastIdentifier - Return true if we have parsed beyond the point where
+ /// the
+ bool isPastIdentifier() const { return IdentifierLoc.isValid(); }
+
+ IdentifierInfo *getIdentifier() const { return Identifier; }
+ SourceLocation getIdentifierLoc() const { return IdentifierLoc; }
+
+ void SetIdentifier(IdentifierInfo *ID, SourceLocation Loc) {
+ Identifier = ID;
+ IdentifierLoc = Loc;
+ }
+
+ void AddTypeInfo(const DeclaratorChunk &TI) {
+ DeclTypeInfo.push_back(TI);
+ }
+
+ /// getNumTypeObjects() - Return the number of types applied to this
+ /// declarator.
+ unsigned getNumTypeObjects() const { return DeclTypeInfo.size(); }
+
+ /// Return the specified TypeInfo from this declarator. TypeInfo #0 is
+ /// closest to the identifier.
+ const DeclaratorChunk &getTypeObject(unsigned i) const {
+ assert(i < DeclTypeInfo.size() && "Invalid type chunk");
+ return DeclTypeInfo[i];
+ }
+ DeclaratorChunk &getTypeObject(unsigned i) {
+ assert(i < DeclTypeInfo.size() && "Invalid type chunk");
+ return DeclTypeInfo[i];
+ }
+
+ /// isFunctionDeclarator - Once this declarator is fully parsed and formed,
+ /// this method returns true if the identifier is a function declarator.
+ bool isFunctionDeclarator() const {
+ return !DeclTypeInfo.empty() &&
+ DeclTypeInfo[0].Kind == DeclaratorChunk::Function;
+ }
+
+ /// AddAttributes - simply adds the attribute list to the Declarator.
+ /// Unlike AddAttributes on DeclSpec, this routine should never have to
+ /// concatenate two lists. The following syntax adds 3 attributes to "var":
+ ///
+ /// short int var __attribute__((aligned(16),common,deprecated));
+ ///
+ void AddAttributes(AttributeList *alist) {
+ if (!alist)
+ return; // we parsed __attribute__(()) or had a syntax error
+ assert((AttrList == 0) && "Declarator already has an attribute list");
+ AttrList = alist;
+ }
+ AttributeList *getAttributes() const { return AttrList; }
+};
+
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
new file mode 100644
index 0000000..19bee27
--- /dev/null
+++ b/include/clang/Parse/Parser.h
@@ -0,0 +1,371 @@
+//===--- Parser.h - C Language Parser ---------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the Parser interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PARSE_PARSER_H
+#define LLVM_CLANG_PARSE_PARSER_H
+
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Parse/Action.h"
+
+namespace clang {
+ class DeclSpec;
+ class Declarator;
+ class AttributeList;
+ class Scope;
+
+/// Parser - This implements a parser for the C family of languages. After
+/// parsing units of the grammar, productions are invoked to handle whatever has
+/// been read.
+///
+class Parser {
+ Preprocessor &PP;
+
+ /// Tok - The current token we are peeking head. All parsing methods assume
+ /// that this is valid.
+ LexerToken Tok;
+
+ unsigned short ParenCount, BracketCount, BraceCount;
+
+ /// Actions - These are the callbacks we invoke as we parse various constructs
+ /// in the file. This refers to the common base class between MinimalActions
+ /// and SemaActions for those uses that don't matter.
+ Action &Actions;
+
+ Scope *CurScope;
+ Diagnostic &Diags;
+public:
+ Parser(Preprocessor &PP, Action &Actions);
+ ~Parser();
+
+ const LangOptions &getLang() const { return PP.getLangOptions(); }
+ TargetInfo &getTargetInfo() const { return PP.getTargetInfo(); }
+ Action &getActions() const { return Actions; }
+
+ // Type forwarding. All of these are statically 'void*', but they may all be
+ // different actual classes based on the actions in place.
+ typedef Action::ExprTy ExprTy;
+ typedef Action::StmtTy StmtTy;
+ typedef Action::DeclTy DeclTy;
+ typedef Action::TypeTy TypeTy;
+
+ // Parsing methods.
+
+ /// ParseTranslationUnit - All in one method that initializes parses, and
+ /// shuts down the parser.
+ void ParseTranslationUnit();
+
+ /// Initialize - Warm up the parser.
+ ///
+ void Initialize();
+
+ /// ParseTopLevelDecl - Parse one top-level declaration, return whatever the
+ /// action tells us to. This returns true if the EOF was encountered.
+ bool ParseTopLevelDecl(DeclTy*& Result);
+
+ /// Finalize - Shut down the parser.
+ ///
+ void Finalize();
+
+private:
+ //===--------------------------------------------------------------------===//
+ // Low-Level token peeking and consumption methods.
+ //
+
+ /// isTokenParen - Return true if the cur token is '(' or ')'.
+ bool isTokenParen() const {
+ return Tok.getKind() == tok::l_paren || Tok.getKind() == tok::r_paren;
+ }
+ /// isTokenBracket - Return true if the cur token is '[' or ']'.
+ bool isTokenBracket() const {
+ return Tok.getKind() == tok::l_square || Tok.getKind() == tok::r_square;
+ }
+ /// isTokenBrace - Return true if the cur token is '{' or '}'.
+ bool isTokenBrace() const {
+ return Tok.getKind() == tok::l_brace || Tok.getKind() == tok::r_brace;
+ }
+
+ /// isTokenStringLiteral - True if this token is a string-literal.
+ ///
+ bool isTokenStringLiteral() const {
+ return Tok.getKind() == tok::string_literal ||
+ Tok.getKind() == tok::wide_string_literal;
+ }
+
+ /// ConsumeToken - Consume the current 'peek token' and lex the next one.
+ /// This does not work will all kinds of tokens: strings and specific other
+ /// tokens must be consumed with custom methods below. This returns the
+ /// location of the consumed token.
+ SourceLocation ConsumeToken() {
+ assert(!isTokenStringLiteral() && !isTokenParen() && !isTokenBracket() &&
+ !isTokenBrace() &&
+ "Should consume special tokens with Consume*Token");
+ SourceLocation L = Tok.getLocation();
+ PP.Lex(Tok);
+ return L;
+ }
+
+ /// ConsumeAnyToken - Dispatch to the right Consume* method based on the
+ /// current token type. This should only be used in cases where the type of
+ /// the token really isn't known, e.g. in error recovery.
+ SourceLocation ConsumeAnyToken() {
+ if (isTokenParen())
+ return ConsumeParen();
+ else if (isTokenBracket())
+ return ConsumeBracket();
+ else if (isTokenBrace())
+ return ConsumeBrace();
+ else
+ return ConsumeToken();
+ }
+
+ /// ConsumeParen - This consume method keeps the paren count up-to-date.
+ ///
+ SourceLocation ConsumeParen() {
+ assert(isTokenParen() && "wrong consume method");
+ if (Tok.getKind() == tok::l_paren)
+ ++ParenCount;
+ else if (ParenCount)
+ --ParenCount; // Don't let unbalanced )'s drive the count negative.
+ SourceLocation L = Tok.getLocation();
+ PP.Lex(Tok);
+ return L;
+ }
+
+ /// ConsumeBracket - This consume method keeps the bracket count up-to-date.
+ ///
+ SourceLocation ConsumeBracket() {
+ assert(isTokenBracket() && "wrong consume method");
+ if (Tok.getKind() == tok::l_square)
+ ++BracketCount;
+ else if (BracketCount)
+ --BracketCount; // Don't let unbalanced ]'s drive the count negative.
+
+ SourceLocation L = Tok.getLocation();
+ PP.Lex(Tok);
+ return L;
+ }
+
+ /// ConsumeBrace - This consume method keeps the brace count up-to-date.
+ ///
+ SourceLocation ConsumeBrace() {
+ assert(isTokenBrace() && "wrong consume method");
+ if (Tok.getKind() == tok::l_brace)
+ ++BraceCount;
+ else if (BraceCount)
+ --BraceCount; // Don't let unbalanced }'s drive the count negative.
+
+ SourceLocation L = Tok.getLocation();
+ PP.Lex(Tok);
+ return L;
+ }
+
+ /// ConsumeStringToken - Consume the current 'peek token', lexing a new one
+ /// and returning the token kind. This method is specific to strings, as it
+ /// handles string literal concatenation, as per C99 5.1.1.2, translation
+ /// phase #6.
+ SourceLocation ConsumeStringToken() {
+ assert(isTokenStringLiteral() &&
+ "Should only consume string literals with this method");
+ SourceLocation L = Tok.getLocation();
+ PP.Lex(Tok);
+ return L;
+ }
+
+ /// MatchRHSPunctuation - For punctuation with a LHS and RHS (e.g. '['/']'),
+ /// this helper function matches and consumes the specified RHS token if
+ /// present. If not present, it emits the specified diagnostic indicating
+ /// that the parser failed to match the RHS of the token at LHSLoc. LHSName
+ /// should be the name of the unmatched LHS token. This returns the location
+ /// of the consumed token.
+ SourceLocation MatchRHSPunctuation(tok::TokenKind RHSTok,
+ SourceLocation LHSLoc);
+
+ /// ExpectAndConsume - The parser expects that 'ExpectedTok' is next in the
+ /// input. If so, it is consumed and false is returned.
+ ///
+ /// If the input is malformed, this emits the specified diagnostic. Next, if
+ /// SkipToTok is specified, it calls SkipUntil(SkipToTok). Finally, true is
+ /// returned.
+ bool ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned Diag,
+ const char *DiagMsg = "",
+ tok::TokenKind SkipToTok = tok::unknown);
+
+ //===--------------------------------------------------------------------===//
+ // Scope manipulation
+
+ /// EnterScope - Start a new scope.
+ void EnterScope(unsigned ScopeFlags);
+
+ /// ExitScope - Pop a scope off the scope stack.
+ void ExitScope();
+
+ //===--------------------------------------------------------------------===//
+ // Diagnostic Emission and Error recovery.
+
+ void Diag(SourceLocation Loc, unsigned DiagID,
+ const std::string &Msg = std::string());
+ void Diag(const LexerToken &Tok, unsigned DiagID,
+ const std::string &M = std::string()) {
+ Diag(Tok.getLocation(), DiagID, M);
+ }
+
+ /// SkipUntil - Read tokens until we get to the specified token, then consume
+ /// it (unless DontConsume is false). Because we cannot guarantee that the
+ /// token will ever occur, this skips to the next token, or to some likely
+ /// good stopping point. If StopAtSemi is true, skipping will stop at a ';'
+ /// character.
+ ///
+ /// If SkipUntil finds the specified token, it returns true, otherwise it
+ /// returns false.
+ bool SkipUntil(tok::TokenKind T, bool StopAtSemi = true,
+ bool DontConsume = false) {
+ return SkipUntil(&T, 1, StopAtSemi, DontConsume);
+ }
+ bool SkipUntil(tok::TokenKind T1, tok::TokenKind T2, bool StopAtSemi = true,
+ bool DontConsume = false) {
+ tok::TokenKind TokArray[] = {T1, T2};
+ return SkipUntil(TokArray, 2, StopAtSemi, DontConsume);
+ }
+ bool SkipUntil(const tok::TokenKind *Toks, unsigned NumToks,
+ bool StopAtSemi = true, bool DontConsume = false);
+
+ //===--------------------------------------------------------------------===//
+ // C99 6.9: External Definitions.
+ DeclTy *ParseExternalDeclaration();
+ DeclTy *ParseDeclarationOrFunctionDefinition();
+ DeclTy *ParseFunctionDefinition(Declarator &D);
+ void ParseKNRParamDeclarations(Declarator &D);
+ void ParseSimpleAsm();
+ void ParseAsmStringLiteral();
+
+ // Objective-C External Declarations
+ void ParseObjCAtDirectives();
+ void ParseObjCAtClassDeclaration(SourceLocation atLoc);
+ void ParseObjCAtInterfaceDeclaration();
+ void ParseObjCAtProtocolDeclaration();
+ void ParseObjCAtImplementationDeclaration();
+ void ParseObjCAtEndDeclaration();
+ void ParseObjCAtAliasDeclaration();
+
+ void ParseObjCInstanceMethodDeclaration();
+ void ParseObjCClassMethodDeclaration();
+
+ //===--------------------------------------------------------------------===//
+ // C99 6.5: Expressions.
+
+ typedef Action::ExprResult ExprResult;
+ typedef Action::StmtResult StmtResult;
+
+ ExprResult ParseExpression();
+ ExprResult ParseConstantExpression();
+ ExprResult ParseAssignmentExpression(); // Expr that doesn't include commas.
+
+ ExprResult ParseExpressionWithLeadingIdentifier(const LexerToken &Tok);
+ ExprResult ParseAssignmentExprWithLeadingIdentifier(const LexerToken &Tok);
+ ExprResult ParseAssignmentExpressionWithLeadingStar(const LexerToken &Tok);
+
+ ExprResult ParseRHSOfBinaryExpression(ExprResult LHS, unsigned MinPrec);
+ ExprResult ParseCastExpression(bool isUnaryExpression);
+ ExprResult ParsePostfixExpressionSuffix(ExprResult LHS);
+ ExprResult ParseSizeofAlignofExpression();
+ ExprResult ParseBuiltinPrimaryExpression();
+
+ /// ParenParseOption - Control what ParseParenExpression will parse.
+ enum ParenParseOption {
+ SimpleExpr, // Only parse '(' expression ')'
+ CompoundStmt, // Also allow '(' compound-statement ')'
+ CompoundLiteral, // Also allow '(' type-name ')' '{' ... '}'
+ CastExpr // Also allow '(' type-name ')' <anything>
+ };
+ ExprResult ParseParenExpression(ParenParseOption &ExprType, TypeTy *&CastTy,
+ SourceLocation &RParenLoc);
+
+ ExprResult ParseSimpleParenExpression() { // Parse SimpleExpr only.
+ SourceLocation RParenLoc;
+ return ParseSimpleParenExpression(RParenLoc);
+ }
+ ExprResult ParseSimpleParenExpression(SourceLocation &RParenLoc) {
+ ParenParseOption Op = SimpleExpr;
+ TypeTy *CastTy;
+ return ParseParenExpression(Op, CastTy, RParenLoc);
+ }
+ ExprResult ParseStringLiteralExpression();
+
+ //===--------------------------------------------------------------------===//
+ // C++ 5.2p1: C++ Casts
+ ExprResult ParseCXXCasts();
+
+ //===--------------------------------------------------------------------===//
+ // C++ 2.13.5: C++ Boolean Literals
+ ExprResult ParseCXXBoolLiteral();
+
+ //===--------------------------------------------------------------------===//
+ // C99 6.7.8: Initialization.
+ ExprResult ParseInitializer();
+ ExprResult ParseInitializerWithPotentialDesignator();
+
+ //===--------------------------------------------------------------------===//
+ // C99 6.8: Statements and Blocks.
+
+ StmtResult ParseStatement() { return ParseStatementOrDeclaration(true); }
+ StmtResult ParseStatementOrDeclaration(bool OnlyStatement = false);
+ StmtResult ParseIdentifierStatement(bool OnlyStatement);
+ StmtResult ParseCaseStatement();
+ StmtResult ParseDefaultStatement();
+ StmtResult ParseCompoundStatement();
+ StmtResult ParseCompoundStatementBody();
+ StmtResult ParseIfStatement();
+ StmtResult ParseSwitchStatement();
+ StmtResult ParseWhileStatement();
+ StmtResult ParseDoStatement();
+ StmtResult ParseForStatement();
+ StmtResult ParseGotoStatement();
+ StmtResult ParseContinueStatement();
+ StmtResult ParseBreakStatement();
+ StmtResult ParseReturnStatement();
+ StmtResult ParseAsmStatement();
+ void ParseAsmOperandsOpt();
+
+ //===--------------------------------------------------------------------===//
+ // C99 6.7: Declarations.
+
+ DeclTy *ParseDeclaration(unsigned Context);
+ DeclTy *ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D);
+ void ParseDeclarationSpecifiers(DeclSpec &DS);
+ void ParseSpecifierQualifierList(DeclSpec &DS);
+
+ bool ParseTag(DeclTy *&Decl, unsigned TagType, SourceLocation StartLoc);
+ void ParseEnumSpecifier(DeclSpec &DS);
+ void ParseEnumBody(SourceLocation StartLoc, DeclTy *TagDecl);
+ void ParseStructUnionSpecifier(DeclSpec &DS);
+ void ParseStructUnionBody(SourceLocation StartLoc, unsigned TagType,
+ DeclTy *TagDecl);
+
+ bool isDeclarationSpecifier() const;
+ bool isTypeSpecifierQualifier() const;
+
+ TypeTy *ParseTypeName();
+ AttributeList *ParseAttributes();
+
+ /// ParseDeclarator - Parse and verify a newly-initialized declarator.
+ void ParseDeclarator(Declarator &D);
+ void ParseDeclaratorInternal(Declarator &D);
+ void ParseTypeQualifierListOpt(DeclSpec &DS);
+ void ParseDirectDeclarator(Declarator &D);
+ void ParseParenDeclarator(Declarator &D);
+ void ParseBracketDeclarator(Declarator &D);
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Parse/Scope.h b/include/clang/Parse/Scope.h
new file mode 100644
index 0000000..367bbf2
--- /dev/null
+++ b/include/clang/Parse/Scope.h
@@ -0,0 +1,146 @@
+//===--- Scope.h - Scope interface ------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the Scope interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PARSE_SCOPE_H
+#define LLVM_CLANG_PARSE_SCOPE_H
+
+#include "clang/Parse/Action.h"
+#include "llvm/ADT/SmallPtrSet.h"
+
+namespace clang {
+
+/// Scope - A scope is a transient data structure that is used while parsing the
+/// program. It assists with resolving identifiers to the appropriate
+/// declaration.
+///
+class Scope {
+public:
+ /// ScopeFlags - These are bitfields that are or'd together when creating a
+ /// scope, which defines the sorts of things the scope contains.
+ enum ScopeFlags {
+ /// FnScope - This indicates that the scope corresponds to a function, which
+ /// means that labels are set here.
+ FnScope = 0x01,
+
+ /// BreakScope - This is a while,do,switch,for, etc that can have break
+ /// stmts embedded into it.
+ BreakScope = 0x02,
+
+ /// ContinueScope - This is a while,do,for, which can have continue
+ /// stmt embedded into it.
+ ContinueScope = 0x04,
+
+ /// HasBreak - This flag is set on 'BreakScope' scopes, when they actually
+ /// do contain a break stmt.
+ HasBreak = 0x08,
+
+ /// HasContinue - This flag is set on 'ContinueScope' scopes, when they
+ /// actually do contain a continue stmt.
+ HasContinue = 0x10
+ };
+private:
+ /// The parent scope for this scope. This is null for the translation-unit
+ /// scope.
+ Scope *AnyParent;
+
+ /// Depth - This is the depth of this scope. The translation-unit scope has
+ /// depth 0.
+ unsigned Depth : 16;
+
+ /// Flags - This contains a set of ScopeFlags, which indicates how the scope
+ /// interrelates with other control flow statements.
+ unsigned Flags : 8;
+
+ /// FnParent - If this scope has a parent scope that is a function body, this
+ /// pointer is non-null and points to it. This is used for label processing.
+ Scope *FnParent;
+
+ /// BreakParent/ContinueParent - This is a direct link to the immediately
+ /// preceeding BreakParent/ContinueParent if this scope is not one, or null if
+ /// there is no containing break/continue scope.
+ Scope *BreakParent, *ContinueParent;
+
+ /// DeclsInScope - This keeps track of all declarations in this scope. When
+ /// the declaration is added to the scope, it is set as the current
+ /// declaration for the identifier in the IdentifierTable. When the scope is
+ /// popped, these declarations are removed from the IdentifierTable's notion
+ /// of current declaration. It is up to the current Action implementation to
+ /// implement these semantics.
+ typedef llvm::SmallPtrSet<Action::DeclTy*, 32> DeclSetTy;
+ DeclSetTy DeclsInScope;
+public:
+ Scope(Scope *Parent, unsigned ScopeFlags) {
+ Init(Parent, ScopeFlags);
+ }
+
+ /// getParent - Return the scope that this is nested in.
+ ///
+ Scope *getParent() const { return AnyParent; }
+
+ /// getContinueParent - Return the closest scope that a continue statement
+ /// would be affected by.
+ Scope *getContinueParent() const {
+ return ContinueParent;
+ }
+
+ /// getBreakParent - Return the closest scope that a break statement
+ /// would be affected by.
+ Scope *getBreakParent() const {
+ return BreakParent;
+ }
+
+
+ typedef DeclSetTy::iterator decl_iterator;
+ decl_iterator decl_begin() const { return DeclsInScope.begin(); }
+ decl_iterator decl_end() const { return DeclsInScope.end(); }
+
+ void AddDecl(Action::DeclTy *D) {
+ DeclsInScope.insert(D);
+ }
+
+ /// isDeclScope - Return true if this is the scope that the specified decl is
+ /// declared in.
+ bool isDeclScope(Action::DeclTy *D) {
+ return DeclsInScope.count(D) != 0;
+ }
+
+
+ /// Init - This is used by the parser to implement scope caching.
+ ///
+ void Init(Scope *Parent, unsigned ScopeFlags) {
+ assert((ScopeFlags & (HasBreak|HasContinue)) == 0 &&
+ "These flags can't be set in ctor!");
+ AnyParent = Parent;
+ Depth = AnyParent ? AnyParent->Depth+1 : 0;
+ Flags = ScopeFlags;
+
+ if (AnyParent) {
+ FnParent = AnyParent->FnParent;
+ BreakParent = AnyParent->BreakParent;
+ ContinueParent = AnyParent->ContinueParent;
+ } else {
+ FnParent = BreakParent = ContinueParent = 0;
+ }
+
+ // If this scope is a function or contains breaks/continues, remember it.
+ if (Flags & FnScope) FnParent = this;
+ if (Flags & BreakScope) BreakParent = this;
+ if (Flags & ContinueScope) ContinueParent = this;
+
+ DeclsInScope.clear();
+ }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Sema/ASTStreamer.h b/include/clang/Sema/ASTStreamer.h
new file mode 100644
index 0000000..f55f871
--- /dev/null
+++ b/include/clang/Sema/ASTStreamer.h
@@ -0,0 +1,45 @@
+//===--- ASTStreamer.h - Stream ASTs for top-level decls --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ASTStreamer interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_ASTSTREAMER_H
+#define LLVM_CLANG_AST_ASTSTREAMER_H
+
+namespace clang {
+ class Preprocessor;
+ class ASTContext;
+ class Decl;
+
+ /// ASTStreamerTy - This is an opaque type used to reference ASTStreamer
+ /// objects.
+ typedef void ASTStreamerTy;
+
+ /// ASTStreamer_Init - Create an ASTStreamer with the specified ASTContext
+ /// and FileID.
+ ASTStreamerTy *ASTStreamer_Init(Preprocessor &pp, ASTContext &ctxt,
+ unsigned MainFileID);
+
+ /// ASTStreamer_ReadTopLevelDecl - Parse and return one top-level declaration.
+ /// This returns null at end of file.
+ Decl *ASTStreamer_ReadTopLevelDecl(ASTStreamerTy *Streamer);
+
+ /// ASTStreamer_PrintStats - Emit statistic information to stderr.
+ ///
+ void ASTStreamer_PrintStats(ASTStreamerTy *Streamer);
+
+ /// ASTStreamer_Terminate - Gracefully shut down the streamer.
+ ///
+ void ASTStreamer_Terminate(ASTStreamerTy *Streamer);
+
+} // end namespace clang
+
+#endif