aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorRoman Divacky <rdivacky@FreeBSD.org>2009-10-23 14:22:18 +0000
committerRoman Divacky <rdivacky@FreeBSD.org>2009-10-23 14:22:18 +0000
commit73490b890977362d28dd6326843a1ecae413921d (patch)
tree3fdd91eae574e32453a4baf462961c742df2691a /include
parenta5f348eb914e67b51914117fac117c18c1f8d650 (diff)
downloadsrc-73490b890977362d28dd6326843a1ecae413921d.tar.gz
src-73490b890977362d28dd6326843a1ecae413921d.zip
Update clang to r84949.vendor/clang/clang-r84949
Notes
Notes: svn path=/vendor/clang/dist/; revision=198398 svn path=/vendor/clang/clang-r84949/; revision=198399; tag=vendor/clang/clang-r84949
Diffstat (limited to 'include')
-rw-r--r--include/clang-c/Index.h89
-rw-r--r--include/clang/AST/ASTContext.h82
-rw-r--r--include/clang/AST/Attr.h1
-rw-r--r--include/clang/AST/CXXInheritance.h3
-rw-r--r--include/clang/AST/CanonicalType.h26
-rw-r--r--include/clang/AST/Decl.h50
-rw-r--r--include/clang/AST/DeclBase.h36
-rw-r--r--include/clang/AST/DeclObjC.h36
-rw-r--r--include/clang/AST/Expr.h25
-rw-r--r--include/clang/AST/Type.h255
-rw-r--r--include/clang/AST/TypeLoc.h690
-rw-r--r--include/clang/AST/TypeLocBuilder.h122
-rw-r--r--include/clang/AST/TypeLocNodes.def46
-rw-r--r--include/clang/AST/TypeLocVisitor.h44
-rw-r--r--include/clang/AST/TypeNodes.def5
-rw-r--r--include/clang/Analysis/PathSensitive/AnalysisContext.h8
-rw-r--r--include/clang/Analysis/PathSensitive/AnalysisManager.h5
-rw-r--r--include/clang/Analysis/PathSensitive/Store.h5
-rw-r--r--include/clang/Analysis/Support/BumpVector.h6
-rw-r--r--include/clang/Basic/Diagnostic.h27
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td3
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td26
-rw-r--r--include/clang/Basic/FileManager.h55
-rw-r--r--include/clang/Basic/IdentifierTable.h25
-rw-r--r--include/clang/Basic/OnDiskHashTable.h21
-rw-r--r--include/clang/Basic/SourceManager.h27
-rw-r--r--include/clang/Basic/TargetInfo.h17
-rw-r--r--include/clang/Frontend/ASTUnit.h38
-rw-r--r--include/clang/Frontend/PCHBitCodes.h65
-rw-r--r--include/clang/Frontend/PCHReader.h16
-rw-r--r--include/clang/Frontend/PCHWriter.h43
-rw-r--r--include/clang/Index/ASTLocation.h6
-rw-r--r--include/clang/Index/Indexer.h13
-rw-r--r--include/clang/Index/Utils.h6
-rw-r--r--include/clang/Parse/Action.h46
35 files changed, 1303 insertions, 665 deletions
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
index 3178017e45be..44cbe0efff81 100644
--- a/include/clang-c/Index.h
+++ b/include/clang-c/Index.h
@@ -99,18 +99,84 @@ typedef struct {
} CXCursor;
/* A unique token for looking up "visible" CXDecls from a CXTranslationUnit. */
-typedef void *CXEntity;
+typedef void *CXEntity;
-CXIndex clang_createIndex();
+/**
+ * \brief clang_createIndex() provides a shared context for creating
+ * translation units. It provides two options:
+ *
+ * - excludeDeclarationsFromPCH: When non-zero, allows enumeration of "local"
+ * declarations (when loading any new translation units). A "local" declaration
+ * is one that belongs in the translation unit itself and not in a precompiled
+ * header that was used by the translation unit. If zero, all declarations
+ * will be enumerated.
+ *
+ * - displayDiagnostics: when non-zero, diagnostics will be output. If zero,
+ * diagnostics will be ignored.
+ *
+ * Here is an example:
+ *
+ * // excludeDeclsFromPCH = 1, displayDiagnostics = 1
+ * Idx = clang_createIndex(1, 1);
+ *
+ * // IndexTest.pch was produced with the following command:
+ * // "clang -x c IndexTest.h -emit-ast -o IndexTest.pch"
+ * TU = clang_createTranslationUnit(Idx, "IndexTest.pch");
+ *
+ * // This will load all the symbols from 'IndexTest.pch'
+ * clang_loadTranslationUnit(TU, TranslationUnitVisitor, 0);
+ * clang_disposeTranslationUnit(TU);
+ *
+ * // This will load all the symbols from 'IndexTest.c', excluding symbols
+ * // from 'IndexTest.pch'.
+ * char *args[] = { "-Xclang", "-include-pch=IndexTest.pch", 0 };
+ * TU = clang_createTranslationUnitFromSourceFile(Idx, "IndexTest.c", 2, args);
+ * clang_loadTranslationUnit(TU, TranslationUnitVisitor, 0);
+ * clang_disposeTranslationUnit(TU);
+ *
+ * This process of creating the 'pch', loading it separately, and using it (via
+ * -include-pch) allows 'excludeDeclsFromPCH' to remove redundant callbacks
+ * (which gives the indexer the same performance benefit as the compiler).
+ */
+CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
+ int displayDiagnostics);
void clang_disposeIndex(CXIndex);
const char *clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit);
+/*
+ * \brief Create a translation unit from an AST file (-emit-ast).
+ */
CXTranslationUnit clang_createTranslationUnit(
CXIndex, const char *ast_filename
);
+/**
+ * \brief Destroy the specified CXTranslationUnit object.
+ */
void clang_disposeTranslationUnit(CXTranslationUnit);
+/**
+ * \brief Return the CXTranslationUnit for a given source file and the provided
+ * command line arguments one would pass to the compiler.
+ *
+ * Note: The 'source_filename' argument is optional. If the caller provides a NULL pointer,
+ * the name of the source file is expected to reside in the specified command line arguments.
+ *
+ * Note: When encountered in 'clang_command_line_args', the following options are ignored:
+ *
+ * '-c'
+ * '-emit-ast'
+ * '-fsyntax-only'
+ * '-o <output file>' (both '-o' and '<output file>' are ignored)
+ *
+ */
+CXTranslationUnit clang_createTranslationUnitFromSourceFile(
+ CXIndex CIdx,
+ const char *source_filename /* specify NULL if the source file is in clang_command_line_args */,
+ int num_clang_command_line_args,
+ const char **clang_command_line_args
+);
+
/*
Usage: clang_loadTranslationUnit(). Will load the toplevel declarations
within a translation unit, issuing a 'callback' for each one.
@@ -182,9 +248,28 @@ const char *clang_getDeclSource(CXDecl);
/*
* CXCursor Operations.
*/
+/**
+ Usage: clang_getCursor() will translate a source/line/column position
+ into an AST cursor (to derive semantic information from the source code).
+ */
CXCursor clang_getCursor(CXTranslationUnit, const char *source_name,
unsigned line, unsigned column);
+/**
+ Usage: clang_getCursorWithHint() provides the same functionality as
+ clang_getCursor() except that it takes an option 'hint' argument.
+ The 'hint' is a temporary CXLookupHint object (whose lifetime is managed by
+ the caller) that should be initialized with clang_initCXLookupHint().
+
+ FIXME: Add a better comment once getCursorWithHint() has more functionality.
+ */
+typedef CXCursor CXLookupHint;
+CXCursor clang_getCursorWithHint(CXTranslationUnit, const char *source_name,
+ unsigned line, unsigned column,
+ CXLookupHint *hint);
+
+void clang_initCXLookupHint(CXLookupHint *hint);
+
enum CXCursorKind clang_getCursorKind(CXCursor);
unsigned clang_isDeclaration(enum CXCursorKind);
unsigned clang_isReference(enum CXCursorKind);
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 106d568c9b24..30896c91a143 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -81,12 +81,12 @@ class ASTContext {
llvm::FoldingSet<DependentTypeOfExprType> DependentTypeOfExprTypes;
llvm::FoldingSet<DependentDecltypeType> DependentDecltypeTypes;
llvm::FoldingSet<TemplateTypeParmType> TemplateTypeParmTypes;
+ llvm::FoldingSet<SubstTemplateTypeParmType> SubstTemplateTypeParmTypes;
llvm::FoldingSet<TemplateSpecializationType> TemplateSpecializationTypes;
llvm::FoldingSet<QualifiedNameType> QualifiedNameTypes;
llvm::FoldingSet<TypenameType> TypenameTypes;
llvm::FoldingSet<ObjCInterfaceType> ObjCInterfaceTypes;
llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
- llvm::FoldingSet<ObjCProtocolListType> ObjCProtocolListTypes;
llvm::FoldingSet<ElaboratedType> ElaboratedTypes;
llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames;
@@ -143,6 +143,12 @@ class ASTContext {
/// \brief The type for the C sigjmp_buf type.
TypeDecl *sigjmp_bufDecl;
+ /// \brief Type for the Block descriptor for Blocks CodeGen.
+ RecordDecl *BlockDescriptorType;
+
+ /// \brief Type for the Block descriptor for Blocks CodeGen.
+ RecordDecl *BlockDescriptorExtendedType;
+
/// \brief Keeps track of all declaration attributes.
///
/// Since so few decls have attrs, we keep them in a hash map instead of
@@ -390,9 +396,47 @@ public:
/// of the specified type.
QualType getBlockPointerType(QualType T);
+ /// This gets the struct used to keep track of the descriptor for pointer to
+ /// blocks.
+ QualType getBlockDescriptorType();
+
+ // Set the type for a Block descriptor type.
+ void setBlockDescriptorType(QualType T);
+ /// Get the BlockDescriptorType type, or NULL if it hasn't yet been built.
+ QualType getRawBlockdescriptorType() {
+ if (BlockDescriptorType)
+ return getTagDeclType(BlockDescriptorType);
+ return QualType();
+ }
+
+ /// This gets the struct used to keep track of the extended descriptor for
+ /// pointer to blocks.
+ QualType getBlockDescriptorExtendedType();
+
+ // Set the type for a Block descriptor extended type.
+ void setBlockDescriptorExtendedType(QualType T);
+ /// Get the BlockDescriptorExtendedType type, or NULL if it hasn't yet been
+ /// built.
+ QualType getRawBlockdescriptorExtendedType() {
+ if (BlockDescriptorExtendedType)
+ return getTagDeclType(BlockDescriptorExtendedType);
+ return QualType();
+ }
+
+ /// This gets the struct used to keep track of pointer to blocks, complete
+ /// with captured variables.
+ QualType getBlockParmType(bool BlockHasCopyDispose,
+ llvm::SmallVector<const Expr *, 8> &BDRDs);
+
+ /// This builds the struct used for __block variables.
+ QualType BuildByRefType(const char *DeclName, QualType Ty);
+
+ /// Returns true iff we need copy/dispose helpers for the given type.
+ bool BlockRequiresCopying(QualType Ty);
+
/// getLValueReferenceType - Return the uniqued reference to the type for an
/// lvalue reference to the specified type.
- QualType getLValueReferenceType(QualType T);
+ QualType getLValueReferenceType(QualType T, bool SpelledAsLValue = true);
/// getRValueReferenceType - Return the uniqued reference to the type for an
/// rvalue reference to the specified type.
@@ -431,22 +475,6 @@ public:
ArrayType::ArraySizeModifier ASM,
unsigned EltTypeQuals);
- /// getConstantArrayWithExprType - Return a reference to the type for a
- /// constant array of the specified element type.
- QualType getConstantArrayWithExprType(QualType EltTy,
- const llvm::APInt &ArySize,
- Expr *ArySizeExpr,
- ArrayType::ArraySizeModifier ASM,
- unsigned EltTypeQuals,
- SourceRange Brackets);
-
- /// getConstantArrayWithoutExprType - Return a reference to the type
- /// for a constant array of the specified element type.
- QualType getConstantArrayWithoutExprType(QualType EltTy,
- const llvm::APInt &ArySize,
- ArrayType::ArraySizeModifier ASM,
- unsigned EltTypeQuals);
-
/// getVectorType - Return the unique reference to a vector type of
/// the specified element type and size. VectorType must be a built-in type.
QualType getVectorType(QualType VectorType, unsigned NumElts);
@@ -485,6 +513,9 @@ public:
/// specified typename decl.
QualType getTypedefType(TypedefDecl *Decl);
+ QualType getSubstTemplateTypeParmType(const TemplateTypeParmType *Replaced,
+ QualType Replacement);
+
QualType getTemplateTypeParmType(unsigned Depth, unsigned Index,
bool ParameterPack,
IdentifierInfo *Name = 0);
@@ -515,10 +546,6 @@ public:
ObjCProtocolDecl **ProtocolList = 0,
unsigned NumProtocols = 0);
- QualType getObjCProtocolListType(QualType T,
- ObjCProtocolDecl **Protocols,
- unsigned NumProtocols);
-
/// getTypeOfType - GCC extension.
QualType getTypeOfExprType(Expr *e);
QualType getTypeOfType(QualType t);
@@ -815,6 +842,12 @@ public:
return T->getCanonicalTypeInternal().getTypePtr();
}
+ /// getCanonicalParamType - Return the canonical parameter type
+ /// corresponding to the specific potentially non-canonical one.
+ /// Qualifiers are stripped off, functions are turned into function
+ /// pointers, and arrays decay one level into pointers.
+ CanQualType getCanonicalParamType(QualType T);
+
/// \brief Determine whether the given types are equivalent.
bool hasSameType(QualType T1, QualType T2) {
return getCanonicalType(T1) == getCanonicalType(T2);
@@ -1047,7 +1080,10 @@ public:
/// \param T the type that will be the basis for type source info. This type
/// should refer to how the declarator was written in source code, not to
/// what type semantic analysis resolved the declarator to.
- DeclaratorInfo *CreateDeclaratorInfo(QualType T);
+ ///
+ /// \param Size the size of the type info to create, or 0 if the size
+ /// should be calculated based on the type.
+ DeclaratorInfo *CreateDeclaratorInfo(QualType T, unsigned Size = 0);
private:
ASTContext(const ASTContext&); // DO NOT IMPLEMENT
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index 6a5e3666a92c..f7a47364a7f6 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -185,7 +185,6 @@ class AlignedAttr : public Attr {
public:
AlignedAttr(unsigned alignment) : Attr(Aligned), Alignment(alignment) {}
- // FIXME: Should use addressable units, not bits, to match llvm
/// getAlignment - The specified alignment in bits.
unsigned getAlignment() const { return Alignment; }
diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h
index a57bcc184a93..7c826fe75d11 100644
--- a/include/clang/AST/CXXInheritance.h
+++ b/include/clang/AST/CXXInheritance.h
@@ -63,7 +63,8 @@ struct CXXBasePathElement {
/// structure, which captures both the link from a derived class to one of its
/// direct bases and identification describing which base class
/// subobject is being used.
-struct CXXBasePath : public llvm::SmallVector<CXXBasePathElement, 4> {
+class CXXBasePath : public llvm::SmallVector<CXXBasePathElement, 4> {
+public:
/// \brief The set of declarations found inside this base class
/// subobject.
DeclContext::lookup_result Decls;
diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h
index d7ac76dd32e4..8b84bc267997 100644
--- a/include/clang/AST/CanonicalType.h
+++ b/include/clang/AST/CanonicalType.h
@@ -487,30 +487,6 @@ struct CanProxyAdaptor<ConstantArrayType>
};
template<>
-struct CanProxyAdaptor<ConstantArrayWithExprType>
- : public CanProxyBase<ConstantArrayWithExprType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
- getSizeModifier)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const llvm::APInt &, getSize)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Expr *, getSizeExpr)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceRange, getBracketsRange)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getLBracketLoc)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(SourceLocation, getRBracketLoc)
-};
-
-template<>
-struct CanProxyAdaptor<ConstantArrayWithoutExprType>
- : public CanProxyBase<ConstantArrayWithoutExprType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(ArrayType::ArraySizeModifier,
- getSizeModifier)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Qualifiers, getIndexTypeQualifiers)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const llvm::APInt &, getSize)
-};
-
-template<>
struct CanProxyAdaptor<IncompleteArrayType>
: public CanProxyBase<IncompleteArrayType> {
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getElementType)
@@ -684,7 +660,7 @@ CanQual<T> CanQual<T>::getFromOpaquePtr(void *Ptr) {
template<typename T>
CanQual<T> CanQual<T>::CreateUnsafe(QualType Other) {
- assert((Other.isNull() || Other->isCanonical()) && "Type is not canonical!");
+ assert((Other.isNull() || Other.isCanonical()) && "Type is not canonical!");
assert((Other.isNull() || isa<T>(Other.getTypePtr())) &&
"Dynamic type does not meet the static type's requires");
CanQual<T> Result;
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index f21541c3e710..72ce0d852cfc 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -47,6 +47,9 @@ class DeclaratorInfo {
friend class ASTContext;
DeclaratorInfo(QualType ty) : Ty(ty) { }
public:
+ /// \brief Return the type wrapped by this type source info.
+ QualType getType() const { return Ty; }
+
/// \brief Return the TypeLoc wrapper for the type source info.
TypeLoc getTypeLoc() const;
};
@@ -93,28 +96,43 @@ public:
/// name (C++ constructor, Objective-C selector, etc.).
IdentifierInfo *getIdentifier() const { return Name.getAsIdentifierInfo(); }
+ /// getName - Get the name of identifier for this declaration as a StringRef.
+ /// This requires that the declaration have a name and that it be a simple
+ /// identifier.
+ llvm::StringRef getName() const {
+ assert(Name.isIdentifier() && "Name is not a simple identifier");
+ return getIdentifier() ? getIdentifier()->getName() : "";
+ }
+
/// getNameAsCString - Get the name of identifier for this declaration as a
/// C string (const char*). This requires that the declaration have a name
/// and that it be a simple identifier.
+ //
+ // FIXME: Deprecated, move clients to getName().
const char *getNameAsCString() const {
- assert(getIdentifier() && "Name is not a simple identifier");
- return getIdentifier()->getName();
+ assert(Name.isIdentifier() && "Name is not a simple identifier");
+ return getIdentifier() ? getIdentifier()->getNameStart() : "";
}
- /// getDeclName - Get the actual, stored name of the declaration,
- /// which may be a special name.
- DeclarationName getDeclName() const { return Name; }
-
- /// \brief Set the name of this declaration.
- void setDeclName(DeclarationName N) { Name = N; }
-
/// getNameAsString - Get a human-readable name for the declaration, even if
/// it is one of the special kinds of names (C++ constructor, Objective-C
/// selector, etc). Creating this name requires expensive string
/// manipulation, so it should be called only when performance doesn't matter.
/// For simple declarations, getNameAsCString() should suffice.
+ //
+ // FIXME: This function should be renamed to indicate that it is not just an
+ // alternate form of getName(), and clients should move as appropriate.
+ //
+ // FIXME: Deprecated, move clients to getName().
std::string getNameAsString() const { return Name.getAsString(); }
+ /// getDeclName - Get the actual, stored name of the declaration,
+ /// which may be a special name.
+ DeclarationName getDeclName() const { return Name; }
+
+ /// \brief Set the name of this declaration.
+ void setDeclName(DeclarationName N) { Name = N; }
+
/// getQualifiedNameAsString - Returns human-readable qualified name for
/// declaration, like A::B::i, for i being member of namespace A::B.
/// If declaration is not member of context which can be named (record,
@@ -604,7 +622,8 @@ public:
/// \brief For a static data member that was instantiated from a static
/// data member of a class template, set the template specialiation kind.
- void setTemplateSpecializationKind(TemplateSpecializationKind TSK);
+ void setTemplateSpecializationKind(TemplateSpecializationKind TSK,
+ SourceLocation PointOfInstantiation = SourceLocation());
/// isFileVarDecl - Returns true for file scoped variable declaration.
bool isFileVarDecl() const {
@@ -1170,7 +1189,16 @@ public:
/// \brief Determine what kind of template instantiation this function
/// represents.
- void setTemplateSpecializationKind(TemplateSpecializationKind TSK);
+ void setTemplateSpecializationKind(TemplateSpecializationKind TSK,
+ SourceLocation PointOfInstantiation = SourceLocation());
+
+ /// \brief Retrieve the (first) point of instantiation of a function template
+ /// specialization or a member of a class template specialization.
+ ///
+ /// \returns the first point of instantiation, if this function was
+ /// instantiated from a template; otherwie, returns an invalid source
+ /// location.
+ SourceLocation getPointOfInstantiation() const;
/// \brief Determine whether this is or was instantiated from an out-of-line
/// definition of a member function.
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index 9e88871565f1..10db7030db18 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -166,6 +166,15 @@ private:
bool Used : 1;
protected:
+ /// Access - Used by C++ decls for the access specifier.
+ // NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum
+ unsigned Access : 2;
+ friend class CXXClassMemberWrapper;
+
+ // PCHLevel - the "level" of precompiled header/AST file from which this
+ // declaration was built.
+ unsigned PCHLevel : 2;
+
/// IdentifierNamespace - This specifies what IDNS_* namespace this lives in.
unsigned IdentifierNamespace : 16;
@@ -177,16 +186,13 @@ private:
#endif
protected:
- /// Access - Used by C++ decls for the access specifier.
- // NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum
- unsigned Access : 2;
- friend class CXXClassMemberWrapper;
Decl(Kind DK, DeclContext *DC, SourceLocation L)
: NextDeclInContext(0), DeclCtx(DC),
Loc(L), DeclKind(DK), InvalidDecl(0),
HasAttrs(false), Implicit(false), Used(false),
- IdentifierNamespace(getIdentifierNamespaceForKind(DK)), Access(AS_none) {
+ Access(AS_none), PCHLevel(0),
+ IdentifierNamespace(getIdentifierNamespaceForKind(DK)) {
if (Decl::CollectingStats()) addDeclKind(DK);
}
@@ -274,6 +280,26 @@ public:
bool isUsed() const { return Used; }
void setUsed(bool U = true) { Used = U; }
+ /// \brief Retrieve the level of precompiled header from which this
+ /// declaration was generated.
+ ///
+ /// The PCH level of a declaration describes where the declaration originated
+ /// from. A PCH level of 0 indicates that the declaration was not from a
+ /// precompiled header. A PCH level of 1 indicates that the declaration was
+ /// from a top-level precompiled header; 2 indicates that the declaration
+ /// comes from a precompiled header on which the top-level precompiled header
+ /// depends, and so on.
+ unsigned getPCHLevel() const { return PCHLevel; }
+
+ /// \brief The maximum PCH level that any declaration may have.
+ static const unsigned MaxPCHLevel = 3;
+
+ /// \brief Set the PCH level of this declaration.
+ void setPCHLevel(unsigned Level) {
+ assert(Level < MaxPCHLevel && "PCH level exceeds the maximum");
+ PCHLevel = Level;
+ }
+
unsigned getIdentifierNamespace() const {
return IdentifierNamespace;
}
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index 2b12bb5c1b6d..729a2f138303 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -944,16 +944,29 @@ public:
ObjCCategoryDecl *getCategoryClass() const;
+ /// getName - Get the name of identifier for the class interface associated
+ /// with this implementation as a StringRef.
+ //
+ // FIXME: This is a bad API, we are overriding the NamedDecl::getName, to mean
+ // something different.
+ llvm::StringRef getName() const {
+ return Id ? Id->getNameStart() : "";
+ }
+
/// getNameAsCString - Get the name of identifier for the class
/// interface associated with this implementation as a C string
/// (const char*).
+ //
+ // FIXME: Deprecated, move clients to getName().
const char *getNameAsCString() const {
- return Id ? Id->getName() : "";
+ return Id ? Id->getNameStart() : "";
}
/// @brief Get the name of the class associated with this interface.
+ //
+ // FIXME: Deprecated, move clients to getName().
std::string getNameAsString() const {
- return Id ? Id->getName() : "";
+ return getName();
}
static bool classof(const Decl *D) { return D->getKind() == ObjCCategoryImpl;}
@@ -995,17 +1008,30 @@ public:
return getClassInterface()->getIdentifier();
}
+ /// getName - Get the name of identifier for the class interface associated
+ /// with this implementation as a StringRef.
+ //
+ // FIXME: This is a bad API, we are overriding the NamedDecl::getName, to mean
+ // something different.
+ llvm::StringRef getName() const {
+ assert(getIdentifier() && "Name is not a simple identifier");
+ return getIdentifier()->getName();
+ }
+
/// getNameAsCString - Get the name of identifier for the class
/// interface associated with this implementation as a C string
/// (const char*).
+ //
+ // FIXME: Move to StringRef API.
const char *getNameAsCString() const {
- assert(getIdentifier() && "Name is not a simple identifier");
- return getIdentifier()->getName();
+ return getName().data();
}
/// @brief Get the name of the class associated with this interface.
+ //
+ // FIXME: Move to StringRef API.
std::string getNameAsString() const {
- return getClassInterface()->getNameAsString();
+ return getName();
}
const ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index d5dff5065d49..0d09ea325c31 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -1399,7 +1399,27 @@ public:
CK_IntegralToPointer,
/// CK_PointerToIntegral - Pointer to integral
- CK_PointerToIntegral
+ CK_PointerToIntegral,
+
+ /// CK_ToVoid - Cast to void.
+ CK_ToVoid,
+
+ /// CK_VectorSplat - Casting from an integer/floating type to an extended
+ /// vector type with the same element type as the src type. Splats the
+ /// src expression into the destination expression.
+ CK_VectorSplat,
+
+ /// CK_IntegralCast - Casting between integral types of different size.
+ CK_IntegralCast,
+
+ /// CK_IntegralToFloating - Integral to floating point.
+ CK_IntegralToFloating,
+
+ /// CK_FloatingToIntegral - Floating point to integral.
+ CK_FloatingToIntegral,
+
+ /// CK_FloatingCast - Casting between floating types of different size.
+ CK_FloatingCast
};
private:
@@ -1665,7 +1685,8 @@ public:
/// 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; }
+ static bool isShiftOp(Opcode Opc) { return Opc == Shl || Opc == Shr; }
+ bool isShiftOp() const { return isShiftOp(Opc); }
bool isBitwiseOp() const { return Opc >= And && Opc <= Or; }
static bool isRelationalOp(Opcode Opc) { return Opc >= LT && Opc <= GE; }
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 89776b91fe4a..db02a68a984d 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -443,6 +443,9 @@ public:
return getTypePtr();
}
+ bool isCanonical() const;
+ bool isCanonicalAsParam() const;
+
/// isNull - Return true if this QualType doesn't point to a type yet.
bool isNull() const {
return Value.getPointer().isNull();
@@ -702,7 +705,9 @@ protected:
public:
TypeClass getTypeClass() const { return static_cast<TypeClass>(TC); }
- bool isCanonical() const { return CanonicalType.getTypePtr() == this; }
+ bool isCanonicalUnqualified() const {
+ return CanonicalType.getTypePtr() == this;
+ }
/// Types are partitioned into 3 broad categories (C99 6.2.5p1):
/// object types, function types, and incomplete types.
@@ -1089,19 +1094,50 @@ public:
class ReferenceType : public Type, public llvm::FoldingSetNode {
QualType PointeeType;
+ /// True if the type was originally spelled with an lvalue sigil.
+ /// This is never true of rvalue references but can also be false
+ /// on lvalue references because of C++0x [dcl.typedef]p9,
+ /// as follows:
+ ///
+ /// typedef int &ref; // lvalue, spelled lvalue
+ /// typedef int &&rvref; // rvalue
+ /// ref &a; // lvalue, inner ref, spelled lvalue
+ /// ref &&a; // lvalue, inner ref
+ /// rvref &a; // lvalue, inner ref, spelled lvalue
+ /// rvref &&a; // rvalue, inner ref
+ bool SpelledAsLValue;
+
+ /// True if the inner type is a reference type. This only happens
+ /// in non-canonical forms.
+ bool InnerRef;
+
protected:
- ReferenceType(TypeClass tc, QualType Referencee, QualType CanonicalRef) :
+ ReferenceType(TypeClass tc, QualType Referencee, QualType CanonicalRef,
+ bool SpelledAsLValue) :
Type(tc, CanonicalRef, Referencee->isDependentType()),
- PointeeType(Referencee) {
+ PointeeType(Referencee), SpelledAsLValue(SpelledAsLValue),
+ InnerRef(Referencee->isReferenceType()) {
}
public:
- QualType getPointeeType() const { return PointeeType; }
+ bool isSpelledAsLValue() const { return SpelledAsLValue; }
+
+ QualType getPointeeTypeAsWritten() const { return PointeeType; }
+ QualType getPointeeType() const {
+ // FIXME: this might strip inner qualifiers; okay?
+ const ReferenceType *T = this;
+ while (T->InnerRef)
+ T = T->PointeeType->getAs<ReferenceType>();
+ return T->PointeeType;
+ }
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getPointeeType());
+ Profile(ID, PointeeType, SpelledAsLValue);
}
- static void Profile(llvm::FoldingSetNodeID &ID, QualType Referencee) {
+ static void Profile(llvm::FoldingSetNodeID &ID,
+ QualType Referencee,
+ bool SpelledAsLValue) {
ID.AddPointer(Referencee.getAsOpaquePtr());
+ ID.AddBoolean(SpelledAsLValue);
}
static bool classof(const Type *T) {
@@ -1114,9 +1150,10 @@ public:
/// LValueReferenceType - C++ [dcl.ref] - Lvalue reference
///
class LValueReferenceType : public ReferenceType {
- LValueReferenceType(QualType Referencee, QualType CanonicalRef) :
- ReferenceType(LValueReference, Referencee, CanonicalRef) {
- }
+ LValueReferenceType(QualType Referencee, QualType CanonicalRef,
+ bool SpelledAsLValue) :
+ ReferenceType(LValueReference, Referencee, CanonicalRef, SpelledAsLValue)
+ {}
friend class ASTContext; // ASTContext creates these
public:
virtual void getAsStringInternal(std::string &InnerString,
@@ -1135,7 +1172,7 @@ public:
///
class RValueReferenceType : public ReferenceType {
RValueReferenceType(QualType Referencee, QualType CanonicalRef) :
- ReferenceType(RValueReference, Referencee, CanonicalRef) {
+ ReferenceType(RValueReference, Referencee, CanonicalRef, false) {
}
friend class ASTContext; // ASTContext creates these
public:
@@ -1239,8 +1276,6 @@ public:
static bool classof(const Type *T) {
return T->getTypeClass() == ConstantArray ||
- T->getTypeClass() == ConstantArrayWithExpr ||
- T->getTypeClass() == ConstantArrayWithoutExpr ||
T->getTypeClass() == VariableArray ||
T->getTypeClass() == IncompleteArray ||
T->getTypeClass() == DependentSizedArray;
@@ -1285,86 +1320,11 @@ public:
ID.AddInteger(TypeQuals);
}
static bool classof(const Type *T) {
- return T->getTypeClass() == ConstantArray ||
- T->getTypeClass() == ConstantArrayWithExpr ||
- T->getTypeClass() == ConstantArrayWithoutExpr;
+ return T->getTypeClass() == ConstantArray;
}
static bool classof(const ConstantArrayType *) { return true; }
};
-/// ConstantArrayWithExprType - This class represents C arrays with a
-/// constant size specified by means of an integer constant expression.
-/// For example 'int A[sizeof(int)]' has ConstantArrayWithExprType where
-/// the element type is 'int' and the size expression is 'sizeof(int)'.
-/// These types are non-canonical.
-class ConstantArrayWithExprType : public ConstantArrayType {
- /// SizeExpr - The ICE occurring in the concrete syntax.
- Expr *SizeExpr;
- /// Brackets - The left and right array brackets.
- SourceRange Brackets;
-
- ConstantArrayWithExprType(QualType et, QualType can,
- const llvm::APInt &size, Expr *e,
- ArraySizeModifier sm, unsigned tq,
- SourceRange brackets)
- : ConstantArrayType(ConstantArrayWithExpr, et, can, size, sm, tq),
- SizeExpr(e), Brackets(brackets) {}
- friend class ASTContext; // ASTContext creates these.
- virtual void Destroy(ASTContext& C);
-
-public:
- Expr *getSizeExpr() const { return SizeExpr; }
- SourceRange getBracketsRange() const { return Brackets; }
- SourceLocation getLBracketLoc() const { return Brackets.getBegin(); }
- SourceLocation getRBracketLoc() const { return Brackets.getEnd(); }
-
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == ConstantArrayWithExpr;
- }
- static bool classof(const ConstantArrayWithExprType *) { return true; }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- assert(0 && "Cannot unique ConstantArrayWithExprTypes.");
- }
-};
-
-/// ConstantArrayWithoutExprType - This class represents C arrays with a
-/// constant size that was not specified by an integer constant expression,
-/// but inferred by static semantics.
-/// For example 'int A[] = { 0, 1, 2 }' has ConstantArrayWithoutExprType.
-/// These types are non-canonical: the corresponding canonical type,
-/// having the size specified in an APInt object, is a ConstantArrayType.
-class ConstantArrayWithoutExprType : public ConstantArrayType {
-
- ConstantArrayWithoutExprType(QualType et, QualType can,
- const llvm::APInt &size,
- ArraySizeModifier sm, unsigned tq)
- : ConstantArrayType(ConstantArrayWithoutExpr, et, can, size, sm, tq) {}
- friend class ASTContext; // ASTContext creates these.
-
-public:
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == ConstantArrayWithoutExpr;
- }
- static bool classof(const ConstantArrayWithoutExprType *) { return true; }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- assert(0 && "Cannot unique ConstantArrayWithoutExprTypes.");
- }
-};
-
/// IncompleteArrayType - This class represents C arrays with an unspecified
/// size. For example 'int A[]' has an IncompleteArrayType where the element
/// type is 'int' and the size is unspecified.
@@ -2219,6 +2179,59 @@ public:
static bool classof(const TemplateTypeParmType *T) { return true; }
};
+/// \brief Represents the result of substituting a type for a template
+/// type parameter.
+///
+/// Within an instantiated template, all template type parameters have
+/// been replaced with these. They are used solely to record that a
+/// type was originally written as a template type parameter;
+/// therefore they are never canonical.
+class SubstTemplateTypeParmType : public Type, public llvm::FoldingSetNode {
+ // The original type parameter.
+ const TemplateTypeParmType *Replaced;
+
+ SubstTemplateTypeParmType(const TemplateTypeParmType *Param, QualType Canon)
+ : Type(SubstTemplateTypeParm, Canon, Canon->isDependentType()),
+ Replaced(Param) { }
+
+ friend class ASTContext;
+
+public:
+ IdentifierInfo *getName() const { return Replaced->getName(); }
+
+ /// Gets the template parameter that was substituted for.
+ const TemplateTypeParmType *getReplacedParameter() const {
+ return Replaced;
+ }
+
+ /// Gets the type that was substituted for the template
+ /// parameter.
+ QualType getReplacementType() const {
+ return getCanonicalTypeInternal();
+ }
+
+ virtual void getAsStringInternal(std::string &InnerString,
+ const PrintingPolicy &Policy) const;
+
+ bool isSugared() const { return true; }
+ QualType desugar() const { return getReplacementType(); }
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, getReplacedParameter(), getReplacementType());
+ }
+ static void Profile(llvm::FoldingSetNodeID &ID,
+ const TemplateTypeParmType *Replaced,
+ QualType Replacement) {
+ ID.AddPointer(Replaced);
+ ID.AddPointer(Replacement.getAsOpaquePtr());
+ }
+
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == SubstTemplateTypeParm;
+ }
+ static bool classof(const SubstTemplateTypeParmType *T) { return true; }
+};
+
/// \brief Represents the type of a template specialization as written
/// in the source code.
///
@@ -2453,9 +2466,9 @@ class ObjCInterfaceType : public Type, public llvm::FoldingSetNode {
// List is sorted on protocol name. No protocol is enterred more than once.
llvm::SmallVector<ObjCProtocolDecl*, 4> Protocols;
- ObjCInterfaceType(ObjCInterfaceDecl *D,
+ ObjCInterfaceType(QualType Canonical, ObjCInterfaceDecl *D,
ObjCProtocolDecl **Protos, unsigned NumP) :
- Type(ObjCInterface, QualType(), /*Dependent=*/false),
+ Type(ObjCInterface, Canonical, /*Dependent=*/false),
Decl(D), Protocols(Protos, Protos+NumP) { }
friend class ASTContext; // ASTContext creates these.
public:
@@ -2501,8 +2514,9 @@ class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode {
// List is sorted on protocol name. No protocol is entered more than once.
llvm::SmallVector<ObjCProtocolDecl*, 8> Protocols;
- ObjCObjectPointerType(QualType T, ObjCProtocolDecl **Protos, unsigned NumP) :
- Type(ObjCObjectPointer, QualType(), /*Dependent=*/false),
+ ObjCObjectPointerType(QualType Canonical, QualType T,
+ ObjCProtocolDecl **Protos, unsigned NumP) :
+ Type(ObjCObjectPointer, Canonical, /*Dependent=*/false),
PointeeType(T), Protocols(Protos, Protos+NumP) { }
friend class ASTContext; // ASTContext creates these.
@@ -2567,49 +2581,6 @@ public:
static bool classof(const ObjCObjectPointerType *) { return true; }
};
-/// \brief An ObjC Protocol list that qualifies a type.
-///
-/// This is used only for keeping detailed type source information, it should
-/// not participate in the semantics of the type system.
-/// The protocol list is not canonicalized.
-class ObjCProtocolListType : public Type, public llvm::FoldingSetNode {
- QualType BaseType;
-
- // List of protocols for this protocol conforming object type.
- llvm::SmallVector<ObjCProtocolDecl*, 4> Protocols;
-
- ObjCProtocolListType(QualType T, ObjCProtocolDecl **Protos, unsigned NumP) :
- Type(ObjCProtocolList, QualType(), /*Dependent=*/false),
- BaseType(T), Protocols(Protos, Protos+NumP) { }
- friend class ASTContext; // ASTContext creates these.
-
-public:
- QualType getBaseType() const { return BaseType; }
-
- /// \brief Provides access to the list of protocols qualifying the base type.
- typedef llvm::SmallVector<ObjCProtocolDecl*, 4>::const_iterator qual_iterator;
-
- qual_iterator qual_begin() const { return Protocols.begin(); }
- qual_iterator qual_end() const { return Protocols.end(); }
- bool qual_empty() const { return Protocols.size() == 0; }
-
- /// \brief Return the number of qualifying protocols.
- unsigned getNumProtocols() const { return Protocols.size(); }
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- void Profile(llvm::FoldingSetNodeID &ID);
- static void Profile(llvm::FoldingSetNodeID &ID, QualType T,
- ObjCProtocolDecl **protocols, unsigned NumProtocols);
- virtual void getAsStringInternal(std::string &InnerString,
- const PrintingPolicy &Policy) const;
- static bool classof(const Type *T) {
- return T->getTypeClass() == ObjCProtocolList;
- }
- static bool classof(const ObjCProtocolListType *) { return true; }
-};
-
/// A qualifier set is used to build a set of qualifiers.
class QualifierCollector : public Qualifiers {
ASTContext *Context;
@@ -2646,6 +2617,20 @@ public:
// Inline function definitions.
+inline bool QualType::isCanonical() const {
+ const Type *T = getTypePtr();
+ if (hasQualifiers())
+ return T->isCanonicalUnqualified() && !isa<ArrayType>(T);
+ return T->isCanonicalUnqualified();
+}
+
+inline bool QualType::isCanonicalAsParam() const {
+ if (hasQualifiers()) return false;
+ const Type *T = getTypePtr();
+ return T->isCanonicalUnqualified() &&
+ !isa<FunctionType>(T) && !isa<ArrayType>(T);
+}
+
inline void QualType::removeConst() {
removeFastQualifiers(Qualifiers::Const);
}
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index 3735eee47629..1d7181b531f8 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -18,10 +18,15 @@
namespace clang {
class ParmVarDecl;
- class TypeSpecLoc;
class DeclaratorInfo;
class UnqualTypeLoc;
+// Predeclare all the type nodes.
+#define ABSTRACT_TYPELOC(Class, Base)
+#define TYPELOC(Class, Base) \
+ class Class##TypeLoc;
+#include "clang/AST/TypeLocNodes.def"
+
/// \brief Base wrapper for a particular "section" of type source info.
///
/// A client should use the TypeLoc subclasses through cast/dyn_cast in order to
@@ -34,12 +39,28 @@ protected:
void *Data;
public:
+ /// The kinds of TypeLocs. Equivalent to the Type::TypeClass enum,
+ /// except it also defines a Qualified enum that corresponds to the
+ /// QualifiedLoc class.
+ enum TypeLocClass {
+#define ABSTRACT_TYPE(Class, Base)
+#define TYPE(Class, Base) \
+ Class = Type::Class,
+#include "clang/AST/TypeNodes.def"
+ Qualified
+ };
+
TypeLoc() : Ty(0), Data(0) { }
TypeLoc(QualType ty, void *opaqueData)
: Ty(ty.getAsOpaquePtr()), Data(opaqueData) { }
TypeLoc(Type *ty, void *opaqueData)
: Ty(ty), Data(opaqueData) { }
+ TypeLocClass getTypeLocClass() const {
+ if (getType().hasQualifiers()) return Qualified;
+ return (TypeLocClass) getType()->getTypeClass();
+ }
+
bool isNull() const { return !Ty; }
operator bool() const { return Ty; }
@@ -48,35 +69,45 @@ public:
/// \brief Get the type for which this source info wrapper provides
/// information.
- QualType getSourceType() const { return QualType::getFromOpaquePtr(Ty); }
+ QualType getType() const {
+ return QualType::getFromOpaquePtr(Ty);
+ }
- Type *getSourceTypePtr() const {
+ Type *getTypePtr() const {
return QualType::getFromOpaquePtr(Ty).getTypePtr();
}
/// \brief Get the pointer where source information is stored.
- void *getOpaqueData() const { return Data; }
-
- SourceRange getSourceRange() const;
-
- /// \brief Find the TypeSpecLoc that is part of this TypeLoc.
- TypeSpecLoc getTypeSpecLoc() const;
+ void *getOpaqueData() const {
+ return Data;
+ }
- /// \brief Find the TypeSpecLoc that is part of this TypeLoc and return its
- /// SourceRange.
- SourceRange getTypeSpecRange() const;
+ SourceRange getSourceRange() const {
+ return getSourceRangeImpl(*this);
+ }
/// \brief Returns the size of the type source info data block.
unsigned getFullDataSize() const {
- return getFullDataSizeForType(getSourceType());
+ return getFullDataSizeForType(getType());
}
/// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
/// TypeLoc is a PointerLoc and next TypeLoc is for "int".
- TypeLoc getNextTypeLoc() const;
+ TypeLoc getNextTypeLoc() const {
+ return getNextTypeLocImpl(*this);
+ }
/// \brief Skips past any qualifiers, if this is qualified.
- UnqualTypeLoc getUnqualifiedLoc() const;
+ UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header
+
+ /// \brief Initializes this to state that every location in this
+ /// type is the given location.
+ ///
+ /// This method exists to provide a simple transition for code that
+ /// relies on location-less types.
+ void initialize(SourceLocation Loc) const {
+ initializeImpl(*this, Loc);
+ }
friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) {
return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data;
@@ -87,6 +118,11 @@ public:
}
static bool classof(const TypeLoc *TL) { return true; }
+
+private:
+ static void initializeImpl(TypeLoc TL, SourceLocation Loc);
+ static TypeLoc getNextTypeLocImpl(TypeLoc TL);
+ static SourceRange getSourceRangeImpl(TypeLoc TL);
};
/// \brief Wrapper of type source information for a type with
@@ -96,12 +132,16 @@ public:
UnqualTypeLoc() {}
UnqualTypeLoc(Type *Ty, void *Data) : TypeLoc(Ty, Data) {}
- Type *getSourceTypePtr() const {
+ Type *getTypePtr() const {
return reinterpret_cast<Type*>(Ty);
}
+ TypeLocClass getTypeLocClass() const {
+ return (TypeLocClass) getTypePtr()->getTypeClass();
+ }
+
static bool classof(const TypeLoc *TL) {
- return !TL->getSourceType().hasQualifiers();
+ return !TL->getType().hasQualifiers();
}
static bool classof(const UnqualTypeLoc *TL) { return true; }
};
@@ -111,14 +151,24 @@ public:
///
/// Currently, we intentionally do not provide source location for
/// type qualifiers.
-class QualifiedLoc : public TypeLoc {
+class QualifiedTypeLoc : public TypeLoc {
public:
SourceRange getSourceRange() const {
return SourceRange();
}
UnqualTypeLoc getUnqualifiedLoc() const {
- return UnqualTypeLoc(getSourceTypePtr(), Data);
+ return UnqualTypeLoc(getTypePtr(), Data);
+ }
+
+ /// Initializes the local data of this type source info block to
+ /// provide no information.
+ void initializeLocal(SourceLocation Loc) {
+ // do nothing
+ }
+
+ TypeLoc getNextTypeLoc() const {
+ return getUnqualifiedLoc();
}
/// \brief Returns the size of the type source info data block that is
@@ -132,52 +182,21 @@ public:
/// \brief Returns the size of the type source info data block.
unsigned getFullDataSize() const {
return getLocalDataSize() +
- getFullDataSizeForType(getSourceType().getUnqualifiedType());
+ getFullDataSizeForType(getType().getUnqualifiedType());
}
static bool classof(const TypeLoc *TL) {
- return TL->getSourceType().hasQualifiers();
+ return TL->getType().hasQualifiers();
}
- static bool classof(const QualifiedLoc *TL) { return true; }
+ static bool classof(const QualifiedTypeLoc *TL) { return true; }
};
inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const {
- if (isa<QualifiedLoc>(this))
- return cast<QualifiedLoc>(this)->getUnqualifiedLoc();
+ if (isa<QualifiedTypeLoc>(this))
+ return cast<QualifiedTypeLoc>(this)->getUnqualifiedLoc();
return cast<UnqualTypeLoc>(*this);
}
-/// \brief Base wrapper of type source info data for type-spec types.
-class TypeSpecLoc : public UnqualTypeLoc {
-public:
- static bool classof(const TypeLoc *TL) {
- return (UnqualTypeLoc::classof(TL) &&
- classof(static_cast<const UnqualTypeLoc*>(TL)));
- }
- static bool classof(const UnqualTypeLoc *TL);
- static bool classof(const TypeSpecLoc *TL) { return true; }
-};
-
-inline SourceRange TypeLoc::getTypeSpecRange() const {
- return getTypeSpecLoc().getSourceRange();
-}
-
-/// \brief Base wrapper of type source info data for types part of a declarator,
-/// excluding type-spec types.
-class DeclaratorLoc : public UnqualTypeLoc {
-public:
- /// \brief Find the TypeSpecLoc that is part of this DeclaratorLoc.
- TypeSpecLoc getTypeSpecLoc() const;
-
- static bool classof(const TypeLoc *TL) {
- return (UnqualTypeLoc::classof(TL) &&
- classof(static_cast<const UnqualTypeLoc*>(TL)));
- }
- static bool classof(const UnqualTypeLoc *TL);
- static bool classof(const DeclaratorLoc *TL) { return true; }
-};
-
-
/// A metaprogramming base class for TypeLoc classes which correspond
/// to a particular Type subclass. It is accepted for a single
/// TypeLoc class to correspond to multiple Type classes.
@@ -196,9 +215,19 @@ public:
/// getExtraLocalDataSize(); getExtraLocalData() will then point to
/// this extra memory.
///
-/// TypeLocs with an inner type should override hasInnerType() and
-/// getInnerType(); getInnerTypeLoc() will then point to this inner
-/// type's location data.
+/// TypeLocs with an inner type should define
+/// QualType getInnerType() const
+/// and getInnerTypeLoc() will then point to this inner type's
+/// location data.
+///
+/// A word about hierarchies: this template is not designed to be
+/// derived from multiple times in a hierarchy. It is also not
+/// designed to be used for classes where subtypes might provide
+/// different amounts of source information. It should be subclassed
+/// only at the deepest portion of the hierarchy where all children
+/// have identical source information; if that's an abstract type,
+/// then further descendents should inherit from
+/// InheritingConcreteTypeLoc instead.
template <class Base, class Derived, class TypeClass, class LocalData>
class ConcreteTypeLoc : public Base {
@@ -215,25 +244,19 @@ public:
return asDerived()->getLocalDataSize() + getInnerTypeSize();
}
- static bool classof(const TypeLoc *TL) {
- return Derived::classofType(TL->getSourceTypePtr());
- }
- static bool classof(const UnqualTypeLoc *TL) {
- return Derived::classofType(TL->getSourceTypePtr());
- }
- static bool classof(const Derived *TL) {
- return true;
- }
-
static bool classofType(const Type *Ty) {
return TypeClass::classof(Ty);
}
-protected:
+ TypeLoc getNextTypeLoc() const {
+ return getNextTypeLoc(asDerived()->getInnerType());
+ }
+
TypeClass *getTypePtr() const {
- return cast<TypeClass>(Base::getSourceTypePtr());
+ return cast<TypeClass>(Base::getTypePtr());
}
+protected:
unsigned getExtraLocalDataSize() const {
return 0;
}
@@ -253,136 +276,151 @@ protected:
return static_cast<char*>(Base::Data) + asDerived()->getLocalDataSize();
}
- bool hasInnerType() const {
- return false;
- }
+ struct HasNoInnerType {};
+ HasNoInnerType getInnerType() const { return HasNoInnerType(); }
TypeLoc getInnerTypeLoc() const {
- assert(asDerived()->hasInnerType());
return TypeLoc(asDerived()->getInnerType(), getNonLocalData());
}
private:
unsigned getInnerTypeSize() const {
- if (asDerived()->hasInnerType())
- return getInnerTypeLoc().getFullDataSize();
+ return getInnerTypeSize(asDerived()->getInnerType());
+ }
+
+ unsigned getInnerTypeSize(HasNoInnerType _) const {
return 0;
}
- // Required here because my metaprogramming is too weak to avoid it.
- QualType getInnerType() const {
- assert(0 && "getInnerType() not overridden");
- return QualType();
+ unsigned getInnerTypeSize(QualType _) const {
+ return getInnerTypeLoc().getFullDataSize();
}
-};
+ TypeLoc getNextTypeLoc(HasNoInnerType _) const {
+ return TypeLoc();
+ }
-struct DefaultTypeSpecLocInfo {
- SourceLocation StartLoc;
+ TypeLoc getNextTypeLoc(QualType T) const {
+ return TypeLoc(T, getNonLocalData());
+ }
};
-/// \brief The default wrapper for type-spec types that are not handled by
-/// another specific wrapper.
-class DefaultTypeSpecLoc : public ConcreteTypeLoc<TypeSpecLoc,
- DefaultTypeSpecLoc,
- Type,
- DefaultTypeSpecLocInfo> {
+/// A metaprogramming class designed for concrete subtypes of abstract
+/// types where all subtypes share equivalently-structured source
+/// information. See the note on ConcreteTypeLoc.
+template <class Base, class Derived, class TypeClass>
+class InheritingConcreteTypeLoc : public Base {
public:
- SourceLocation getStartLoc() const {
- return getLocalData()->StartLoc;
+ static bool classof(const TypeLoc *TL) {
+ return Derived::classofType(TL->getTypePtr());
}
- void setStartLoc(SourceLocation Loc) {
- getLocalData()->StartLoc = Loc;
+ static bool classof(const UnqualTypeLoc *TL) {
+ return Derived::classofType(TL->getTypePtr());
}
- SourceRange getSourceRange() const {
- return SourceRange(getStartLoc(), getStartLoc());
+ static bool classof(const Derived *TL) {
+ return true;
}
- static bool classofType(const Type *T);
+ TypeClass *getTypePtr() const {
+ return cast<TypeClass>(Base::getTypePtr());
+ }
};
-
-struct TypedefLocInfo {
+struct TypeSpecLocInfo {
SourceLocation NameLoc;
};
-/// \brief Wrapper for source info for typedefs.
-class TypedefLoc : public ConcreteTypeLoc<TypeSpecLoc,TypedefLoc,
- TypedefType,TypedefLocInfo> {
+/// \brief A reasonable base class for TypeLocs that correspond to
+/// types that are written as a type-specifier.
+template <class Derived, class TypeClass, class LocalData = TypeSpecLocInfo>
+class TypeSpecTypeLoc
+ : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> {
public:
SourceLocation getNameLoc() const {
- return getLocalData()->NameLoc;
+ return this->getLocalData()->NameLoc;
}
void setNameLoc(SourceLocation Loc) {
- getLocalData()->NameLoc = Loc;
+ this->getLocalData()->NameLoc = Loc;
}
SourceRange getSourceRange() const {
return SourceRange(getNameLoc(), getNameLoc());
}
+ void initializeLocal(SourceLocation Loc) {
+ setNameLoc(Loc);
+ }
+};
+/// \brief Wrapper for source info for typedefs.
+class TypedefTypeLoc : public TypeSpecTypeLoc<TypedefTypeLoc,TypedefType> {
+public:
TypedefDecl *getTypedefDecl() const {
return getTypePtr()->getDecl();
}
};
-struct ObjCInterfaceLocInfo {
- SourceLocation NameLoc;
+/// \brief Wrapper for source info for builtin types.
+class BuiltinTypeLoc : public TypeSpecTypeLoc<BuiltinTypeLoc,
+ BuiltinType> {
};
-/// \brief Wrapper for source info for ObjC interfaces.
-class ObjCInterfaceLoc : public ConcreteTypeLoc<TypeSpecLoc,
- ObjCInterfaceLoc,
- ObjCInterfaceType,
- ObjCInterfaceLocInfo> {
-public:
- SourceLocation getNameLoc() const {
- return getLocalData()->NameLoc;
- }
- void setNameLoc(SourceLocation Loc) {
- getLocalData()->NameLoc = Loc;
- }
- SourceRange getSourceRange() const {
- return SourceRange(getNameLoc(), getNameLoc());
- }
+/// \brief Wrapper for template type parameters.
+class TemplateTypeParmTypeLoc : public TypeSpecTypeLoc<TemplateTypeParmTypeLoc,
+ TemplateTypeParmType> {
+};
- ObjCInterfaceDecl *getIFaceDecl() const {
- return getTypePtr()->getDecl();
- }
+/// \brief Wrapper for substituted template type parameters.
+class SubstTemplateTypeParmTypeLoc :
+ public TypeSpecTypeLoc<SubstTemplateTypeParmTypeLoc,
+ SubstTemplateTypeParmType> {
};
struct ObjCProtocolListLocInfo {
- SourceLocation LAngleLoc, RAngleLoc;
+ SourceLocation LAngleLoc;
+ SourceLocation RAngleLoc;
};
-/// \brief Wrapper for source info for ObjC protocol lists.
-class ObjCProtocolListLoc : public ConcreteTypeLoc<TypeSpecLoc,
- ObjCProtocolListLoc,
- ObjCProtocolListType,
- ObjCProtocolListLocInfo> {
+// A helper class for defining ObjC TypeLocs that can qualified with
+// protocols.
+//
+// TypeClass basically has to be either ObjCInterfaceType or
+// ObjCObjectPointerType.
+template <class Derived, class TypeClass, class LocalData>
+class ObjCProtocolListTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
+ Derived,
+ TypeClass,
+ LocalData> {
// SourceLocations are stored after Info, one for each Protocol.
SourceLocation *getProtocolLocArray() const {
- return (SourceLocation*) getExtraLocalData();
+ return (SourceLocation*) this->getExtraLocalData();
+ }
+
+protected:
+ void initializeLocalBase(SourceLocation Loc) {
+ setLAngleLoc(Loc);
+ setRAngleLoc(Loc);
+ for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
+ setProtocolLoc(i, Loc);
}
public:
SourceLocation getLAngleLoc() const {
- return getLocalData()->LAngleLoc;
+ return this->getLocalData()->LAngleLoc;
}
void setLAngleLoc(SourceLocation Loc) {
- getLocalData()->LAngleLoc = Loc;
+ this->getLocalData()->LAngleLoc = Loc;
}
SourceLocation getRAngleLoc() const {
- return getLocalData()->RAngleLoc;
+ return this->getLocalData()->RAngleLoc;
}
void setRAngleLoc(SourceLocation Loc) {
- getLocalData()->RAngleLoc = Loc;
+ this->getLocalData()->RAngleLoc = Loc;
}
unsigned getNumProtocols() const {
- return getTypePtr()->getNumProtocols();
+ return this->getTypePtr()->getNumProtocols();
}
SourceLocation getProtocolLoc(unsigned i) const {
@@ -396,165 +434,229 @@ public:
ObjCProtocolDecl *getProtocol(unsigned i) const {
assert(i < getNumProtocols() && "Index is out of bounds!");
- return *(getTypePtr()->qual_begin() + i);
+ return *(this->getTypePtr()->qual_begin() + i);
}
- TypeLoc getBaseTypeLoc() const {
- return getInnerTypeLoc();
- }
-
SourceRange getSourceRange() const {
return SourceRange(getLAngleLoc(), getRAngleLoc());
}
- /// \brief Returns the size of the type source info data block that is
- /// specific to this type.
- unsigned getExtraLocalDataSize() const {
- return getNumProtocols() * sizeof(SourceLocation);
+ void initializeLocal(SourceLocation Loc) {
+ initializeLocalBase(Loc);
}
- bool hasInnerType() const { return true; }
- QualType getInnerType() const { return getTypePtr()->getBaseType(); }
+ unsigned getExtraLocalDataSize() const {
+ return this->getNumProtocols() * sizeof(SourceLocation);
+ }
};
-struct PointerLocInfo {
- SourceLocation StarLoc;
+struct ObjCInterfaceLocInfo : ObjCProtocolListLocInfo {
+ SourceLocation NameLoc;
};
-/// \brief Wrapper for source info for pointers.
-class PointerLoc : public ConcreteTypeLoc<DeclaratorLoc,
- PointerLoc,
- PointerType,
- PointerLocInfo> {
+/// \brief Wrapper for source info for ObjC interfaces.
+class ObjCInterfaceTypeLoc :
+ public ObjCProtocolListTypeLoc<ObjCInterfaceTypeLoc,
+ ObjCInterfaceType,
+ ObjCInterfaceLocInfo> {
public:
- SourceLocation getStarLoc() const {
- return getLocalData()->StarLoc;
- }
- void setStarLoc(SourceLocation Loc) {
- getLocalData()->StarLoc = Loc;
+ ObjCInterfaceDecl *getIFaceDecl() const {
+ return getTypePtr()->getDecl();
}
- TypeLoc getPointeeLoc() const {
- return getInnerTypeLoc();
+ SourceLocation getNameLoc() const {
+ return getLocalData()->NameLoc;
}
- /// \brief Find the TypeSpecLoc that is part of this PointerLoc.
- TypeSpecLoc getTypeSpecLoc() const {
- return getPointeeLoc().getTypeSpecLoc();
+ void setNameLoc(SourceLocation Loc) {
+ getLocalData()->NameLoc = Loc;
}
SourceRange getSourceRange() const {
- return SourceRange(getStarLoc(), getStarLoc());
+ if (getNumProtocols())
+ return SourceRange(getNameLoc(), getRAngleLoc());
+ else
+ return SourceRange(getNameLoc(), getNameLoc());
}
- bool hasInnerType() const { return true; }
- QualType getInnerType() const { return getTypePtr()->getPointeeType(); }
+ void initializeLocal(SourceLocation Loc) {
+ initializeLocalBase(Loc);
+ setNameLoc(Loc);
+ }
};
-struct BlockPointerLocInfo {
- SourceLocation CaretLoc;
+struct ObjCObjectPointerLocInfo : ObjCProtocolListLocInfo {
+ SourceLocation StarLoc;
+ bool HasProtocols;
+ bool HasBaseType;
};
-/// \brief Wrapper for source info for block pointers.
-class BlockPointerLoc : public ConcreteTypeLoc<DeclaratorLoc,
- BlockPointerLoc,
- BlockPointerType,
- BlockPointerLocInfo> {
+/// Wraps an ObjCPointerType with source location information. Note
+/// that not all ObjCPointerTypes actually have a star location; nor
+/// are protocol locations necessarily written in the source just
+/// because they're present on the type.
+class ObjCObjectPointerTypeLoc :
+ public ObjCProtocolListTypeLoc<ObjCObjectPointerTypeLoc,
+ ObjCObjectPointerType,
+ ObjCObjectPointerLocInfo> {
public:
- SourceLocation getCaretLoc() const {
- return getLocalData()->CaretLoc;
+ bool hasProtocolsAsWritten() const {
+ return getLocalData()->HasProtocols;
}
- void setCaretLoc(SourceLocation Loc) {
- getLocalData()->CaretLoc = Loc;
+
+ void setHasProtocolsAsWritten(bool HasProtocols) {
+ getLocalData()->HasProtocols = HasProtocols;
}
- TypeLoc getPointeeLoc() const {
- return getInnerTypeLoc();
+ bool hasBaseTypeAsWritten() const {
+ return getLocalData()->HasBaseType;
}
- /// \brief Find the TypeSpecLoc that is part of this BlockPointerLoc.
- TypeSpecLoc getTypeSpecLoc() const {
- return getPointeeLoc().getTypeSpecLoc();
+ void setHasBaseTypeAsWritten(bool HasBaseType) {
+ getLocalData()->HasBaseType = HasBaseType;
+ }
+
+ SourceLocation getStarLoc() const {
+ return getLocalData()->StarLoc;
+ }
+
+ void setStarLoc(SourceLocation Loc) {
+ getLocalData()->StarLoc = Loc;
}
SourceRange getSourceRange() const {
- return SourceRange(getCaretLoc(), getCaretLoc());
+ // Being written with protocols is incompatible with being written
+ // with a star.
+ if (hasProtocolsAsWritten())
+ return SourceRange(getLAngleLoc(), getRAngleLoc());
+ else
+ return SourceRange(getStarLoc(), getStarLoc());
+ }
+
+ void initializeLocal(SourceLocation Loc) {
+ initializeLocalBase(Loc);
+ setHasProtocolsAsWritten(false);
+ setHasBaseTypeAsWritten(false);
+ setStarLoc(Loc);
+ }
+
+ TypeLoc getBaseTypeLoc() const {
+ return getInnerTypeLoc();
}
- bool hasInnerType() const { return true; }
- QualType getInnerType() const { return getTypePtr()->getPointeeType(); }
+ QualType getInnerType() const {
+ return getTypePtr()->getPointeeType();
+ }
};
-struct MemberPointerLocInfo {
+struct PointerLikeLocInfo {
SourceLocation StarLoc;
};
-/// \brief Wrapper for source info for member pointers.
-class MemberPointerLoc : public ConcreteTypeLoc<DeclaratorLoc,
- MemberPointerLoc,
- MemberPointerType,
- MemberPointerLocInfo> {
-public:
- SourceLocation getStarLoc() const {
- return getLocalData()->StarLoc;
+/// A base class for
+template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo>
+class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived,
+ TypeClass, LocalData> {
+public:
+ SourceLocation getSigilLoc() const {
+ return this->getLocalData()->StarLoc;
}
- void setStarLoc(SourceLocation Loc) {
- getLocalData()->StarLoc = Loc;
+ void setSigilLoc(SourceLocation Loc) {
+ this->getLocalData()->StarLoc = Loc;
}
TypeLoc getPointeeLoc() const {
- return getInnerTypeLoc();
+ return this->getInnerTypeLoc();
}
- /// \brief Find the TypeSpecLoc that is part of this MemberPointerLoc.
- TypeSpecLoc getTypeSpecLoc() const {
- return getPointeeLoc().getTypeSpecLoc();
+ SourceRange getSourceRange() const {
+ return SourceRange(getSigilLoc(), getSigilLoc());
}
- SourceRange getSourceRange() const {
- return SourceRange(getStarLoc(), getStarLoc());
+ void initializeLocal(SourceLocation Loc) {
+ setSigilLoc(Loc);
}
- bool hasInnerType() const { return true; }
- QualType getInnerType() const { return getTypePtr()->getPointeeType(); }
+ QualType getInnerType() const {
+ return this->getTypePtr()->getPointeeType();
+ }
};
-struct ReferenceLocInfo {
- SourceLocation AmpLoc;
+/// \brief Wrapper for source info for pointers.
+class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc,
+ PointerType> {
+public:
+ SourceLocation getStarLoc() const {
+ return getSigilLoc();
+ }
+ void setStarLoc(SourceLocation Loc) {
+ setSigilLoc(Loc);
+ }
};
-/// \brief Wrapper for source info for references.
-class ReferenceLoc : public ConcreteTypeLoc<DeclaratorLoc,
- ReferenceLoc,
- ReferenceType,
- ReferenceLocInfo> {
+
+/// \brief Wrapper for source info for block pointers.
+class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
+ BlockPointerType> {
public:
- SourceLocation getAmpLoc() const {
- return getLocalData()->AmpLoc;
+ SourceLocation getCaretLoc() const {
+ return getSigilLoc();
}
- void setAmpLoc(SourceLocation Loc) {
- getLocalData()->AmpLoc = Loc;
+ void setCaretLoc(SourceLocation Loc) {
+ setSigilLoc(Loc);
}
+};
- TypeLoc getPointeeLoc() const {
- return TypeLoc(getTypePtr()->getPointeeType(), getNonLocalData());
+
+/// \brief Wrapper for source info for member pointers.
+class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
+ MemberPointerType> {
+public:
+ SourceLocation getStarLoc() const {
+ return getSigilLoc();
+ }
+ void setStarLoc(SourceLocation Loc) {
+ setSigilLoc(Loc);
}
+};
- /// \brief Find the TypeSpecLoc that is part of this ReferenceLoc.
- TypeSpecLoc getTypeSpecLoc() const {
- return getPointeeLoc().getTypeSpecLoc();
+
+class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
+ ReferenceType> {
+public:
+ QualType getInnerType() const {
+ return getTypePtr()->getPointeeTypeAsWritten();
}
+};
- SourceRange getSourceRange() const {
- return SourceRange(getAmpLoc(), getAmpLoc());
+class LValueReferenceTypeLoc :
+ public InheritingConcreteTypeLoc<ReferenceTypeLoc,
+ LValueReferenceTypeLoc,
+ LValueReferenceType> {
+public:
+ SourceLocation getAmpLoc() const {
+ return getSigilLoc();
+ }
+ void setAmpLoc(SourceLocation Loc) {
+ setSigilLoc(Loc);
}
+};
- bool hasInnerType() const { return true; }
- QualType getInnerType() const { return getTypePtr()->getPointeeType(); }
+class RValueReferenceTypeLoc :
+ public InheritingConcreteTypeLoc<ReferenceTypeLoc,
+ RValueReferenceTypeLoc,
+ RValueReferenceType> {
+public:
+ SourceLocation getAmpAmpLoc() const {
+ return getSigilLoc();
+ }
+ void setAmpAmpLoc(SourceLocation Loc) {
+ setSigilLoc(Loc);
+ }
};
@@ -563,10 +665,10 @@ struct FunctionLocInfo {
};
/// \brief Wrapper for source info for functions.
-class FunctionLoc : public ConcreteTypeLoc<DeclaratorLoc,
- FunctionLoc,
- FunctionType,
- FunctionLocInfo> {
+class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
+ FunctionTypeLoc,
+ FunctionType,
+ FunctionLocInfo> {
// ParmVarDecls* are stored after Info, one for each argument.
ParmVarDecl **getParmArray() const {
return (ParmVarDecl**) getExtraLocalData();
@@ -601,24 +703,38 @@ public:
return getInnerTypeLoc();
}
- /// \brief Find the TypeSpecLoc that is part of this FunctionLoc.
- TypeSpecLoc getTypeSpecLoc() const {
- return getResultLoc().getTypeSpecLoc();
- }
SourceRange getSourceRange() const {
return SourceRange(getLParenLoc(), getRParenLoc());
}
+ void initializeLocal(SourceLocation Loc) {
+ setLParenLoc(Loc);
+ setRParenLoc(Loc);
+ for (unsigned i = 0, e = getNumArgs(); i != e; ++i)
+ setArg(i, NULL);
+ }
+
/// \brief Returns the size of the type source info data block that is
/// specific to this type.
unsigned getExtraLocalDataSize() const {
return getNumArgs() * sizeof(ParmVarDecl*);
}
- bool hasInnerType() const { return true; }
QualType getInnerType() const { return getTypePtr()->getResultType(); }
};
+class FunctionProtoTypeLoc :
+ public InheritingConcreteTypeLoc<FunctionTypeLoc,
+ FunctionProtoTypeLoc,
+ FunctionProtoType> {
+};
+
+class FunctionNoProtoTypeLoc :
+ public InheritingConcreteTypeLoc<FunctionTypeLoc,
+ FunctionNoProtoTypeLoc,
+ FunctionNoProtoType> {
+};
+
struct ArrayLocInfo {
SourceLocation LBracketLoc, RBracketLoc;
@@ -626,10 +742,10 @@ struct ArrayLocInfo {
};
/// \brief Wrapper for source info for arrays.
-class ArrayLoc : public ConcreteTypeLoc<DeclaratorLoc,
- ArrayLoc,
- ArrayType,
- ArrayLocInfo> {
+class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
+ ArrayTypeLoc,
+ ArrayType,
+ ArrayLocInfo> {
public:
SourceLocation getLBracketLoc() const {
return getLocalData()->LBracketLoc;
@@ -656,18 +772,108 @@ public:
return getInnerTypeLoc();
}
- /// \brief Find the TypeSpecLoc that is part of this ArrayLoc.
- TypeSpecLoc getTypeSpecLoc() const {
- return getElementLoc().getTypeSpecLoc();
- }
SourceRange getSourceRange() const {
return SourceRange(getLBracketLoc(), getRBracketLoc());
}
- bool hasInnerType() const { return true; }
+ void initializeLocal(SourceLocation Loc) {
+ setLBracketLoc(Loc);
+ setRBracketLoc(Loc);
+ setSizeExpr(NULL);
+ }
+
QualType getInnerType() const { return getTypePtr()->getElementType(); }
};
+class ConstantArrayTypeLoc :
+ public InheritingConcreteTypeLoc<ArrayTypeLoc,
+ ConstantArrayTypeLoc,
+ ConstantArrayType> {
+};
+
+class IncompleteArrayTypeLoc :
+ public InheritingConcreteTypeLoc<ArrayTypeLoc,
+ IncompleteArrayTypeLoc,
+ IncompleteArrayType> {
+};
+
+class DependentSizedArrayTypeLoc :
+ public InheritingConcreteTypeLoc<ArrayTypeLoc,
+ DependentSizedArrayTypeLoc,
+ DependentSizedArrayType> {
+
+};
+
+class VariableArrayTypeLoc :
+ public InheritingConcreteTypeLoc<ArrayTypeLoc,
+ VariableArrayTypeLoc,
+ VariableArrayType> {
+};
+
+// None of these types have proper implementations yet.
+
+class VectorTypeLoc : public TypeSpecTypeLoc<VectorTypeLoc, VectorType> {
+};
+
+class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc,
+ ExtVectorTypeLoc,
+ ExtVectorType> {
+};
+
+// For some reason, this isn't a subtype of VectorType.
+class DependentSizedExtVectorTypeLoc :
+ public TypeSpecTypeLoc<DependentSizedExtVectorTypeLoc,
+ DependentSizedExtVectorType> {
+};
+
+class FixedWidthIntTypeLoc : public TypeSpecTypeLoc<FixedWidthIntTypeLoc,
+ FixedWidthIntType> {
+};
+
+class ComplexTypeLoc : public TypeSpecTypeLoc<ComplexTypeLoc,
+ ComplexType> {
+};
+
+class TypeOfExprTypeLoc : public TypeSpecTypeLoc<TypeOfExprTypeLoc,
+ TypeOfExprType> {
+};
+
+class TypeOfTypeLoc : public TypeSpecTypeLoc<TypeOfTypeLoc, TypeOfType> {
+};
+
+class DecltypeTypeLoc : public TypeSpecTypeLoc<DecltypeTypeLoc, DecltypeType> {
+};
+
+class TagTypeLoc : public TypeSpecTypeLoc<TagTypeLoc, TagType> {
+};
+
+class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
+ RecordTypeLoc,
+ RecordType> {
+};
+
+class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
+ EnumTypeLoc,
+ EnumType> {
+};
+
+class ElaboratedTypeLoc : public TypeSpecTypeLoc<ElaboratedTypeLoc,
+ ElaboratedType> {
+};
+
+class TemplateSpecializationTypeLoc
+ : public TypeSpecTypeLoc<TemplateSpecializationTypeLoc,
+ TemplateSpecializationType> {
+};
+
+class QualifiedNameTypeLoc : public TypeSpecTypeLoc<QualifiedNameTypeLoc,
+ QualifiedNameType> {
+};
+
+class TypenameTypeLoc : public TypeSpecTypeLoc<TypenameTypeLoc,
+ TypenameType> {
+};
+
}
#endif
diff --git a/include/clang/AST/TypeLocBuilder.h b/include/clang/AST/TypeLocBuilder.h
new file mode 100644
index 000000000000..4e1fbaaf4c5e
--- /dev/null
+++ b/include/clang/AST/TypeLocBuilder.h
@@ -0,0 +1,122 @@
+//===--- TypeLocBuilder.h - Type Source Info collector ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This files defines TypeLocBuilder, a class for building TypeLocs
+// bottom-up.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_TYPELOCBUILDER_H
+#define LLVM_CLANG_AST_TYPELOCBUILDER_H
+
+#include "clang/AST/TypeLoc.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+
+class TypeLocBuilder {
+ enum { InlineCapacity = 8 * sizeof(SourceLocation) };
+
+ /// The underlying location-data buffer. Data grows from the end
+ /// of the buffer backwards.
+ char *Buffer;
+
+ /// The capacity of the current buffer.
+ size_t Capacity;
+
+ /// The index of the first occupied byte in the buffer.
+ size_t Index;
+
+#ifndef NDEBUG
+ /// The last type pushed on this builder.
+ QualType LastTy;
+#endif
+
+ /// The inline buffer.
+ char InlineBuffer[InlineCapacity];
+
+ public:
+ TypeLocBuilder()
+ : Buffer(InlineBuffer), Capacity(InlineCapacity), Index(InlineCapacity)
+ {}
+
+ ~TypeLocBuilder() {
+ if (Buffer != InlineBuffer)
+ delete[] Buffer;
+ }
+
+ /// Ensures that this buffer has at least as much capacity as described.
+ void reserve(size_t Requested) {
+ if (Requested > Capacity)
+ // For now, match the request exactly.
+ grow(Requested);
+ }
+
+ /// Pushes space for a new TypeLoc onto the given type. Invalidates
+ /// any TypeLocs previously retrieved from this builder.
+ template <class TyLocType> TyLocType push(QualType T) {
+#ifndef NDEBUG
+ QualType TLast = TypeLoc(T, 0).getNextTypeLoc().getType();
+ assert(TLast == LastTy &&
+ "mismatch between last type and new type's inner type");
+ LastTy = T;
+#endif
+
+ size_t LocalSize = cast<TyLocType>(TypeLoc(T, 0)).getLocalDataSize();
+
+ // If we need to grow, grow by a factor of 2.
+ if (LocalSize > Index) {
+ size_t RequiredCapacity = Capacity + (LocalSize - Index);
+ size_t NewCapacity = Capacity * 2;
+ while (RequiredCapacity > NewCapacity)
+ NewCapacity *= 2;
+ grow(NewCapacity);
+ }
+
+ Index -= LocalSize;
+
+ return cast<TyLocType>(TypeLoc(T, &Buffer[Index]));
+ }
+
+ /// Creates a DeclaratorInfo for the given type.
+ DeclaratorInfo *getDeclaratorInfo(ASTContext& Context, QualType T) {
+#ifndef NDEBUG
+ assert(T == LastTy && "type doesn't match last type pushed!");
+#endif
+
+ size_t FullDataSize = Capacity - Index;
+ DeclaratorInfo *DI = Context.CreateDeclaratorInfo(T, FullDataSize);
+ memcpy(DI->getTypeLoc().getOpaqueData(), &Buffer[Index], FullDataSize);
+ return DI;
+ }
+
+ private:
+ /// Grow to the given capacity.
+ void grow(size_t NewCapacity) {
+ assert(NewCapacity > Capacity);
+
+ // Allocate the new buffer and copy the old data into it.
+ char *NewBuffer = new char[NewCapacity];
+ unsigned NewIndex = Index + NewCapacity - Capacity;
+ memcpy(&NewBuffer[NewIndex],
+ &Buffer[Index],
+ Capacity - Index);
+
+ if (Buffer != InlineBuffer)
+ delete[] Buffer;
+
+ Buffer = NewBuffer;
+ Capacity = NewCapacity;
+ Index = NewIndex;
+ }
+};
+
+}
+
+#endif
diff --git a/include/clang/AST/TypeLocNodes.def b/include/clang/AST/TypeLocNodes.def
index ecf7cc5c2995..4590e489e3f7 100644
--- a/include/clang/AST/TypeLocNodes.def
+++ b/include/clang/AST/TypeLocNodes.def
@@ -7,54 +7,32 @@
//
//===----------------------------------------------------------------------===//
//
-// This file defines the TypeLoc info database. Each node is
-// enumerated by providing its name (e.g., "PointerLoc" or "ArrayLoc"),
-// base class (e.g., "TypeSpecLoc" or "DeclaratorLoc"), and the Type subclass
-// that the TypeLoc is associated with.
+// This file defines the TypeLoc info database. Each node is
+// enumerated by providing its core name (e.g., "Pointer" for "PointerTypeLoc")
+// and base class (e.g., "DeclaratorLoc"). All nodes except QualifiedTypeLoc
+// are associated
//
-// TYPELOC(Class, Base) - A TypeLoc subclass.
+// TYPELOC(Class, Base) - A TypeLoc subclass. If UNQUAL_TYPELOC is
+// provided, there will be exactly one of these, Qualified.
//
// UNQUAL_TYPELOC(Class, Base, Type) - An UnqualTypeLoc subclass.
//
// ABSTRACT_TYPELOC(Class) - Refers to TypeSpecLoc and DeclaratorLoc.
//
-// TYPESPEC_TYPELOC(Class, Type) - A TypeLoc referring to a type-spec type.
-//
-// DECLARATOR_TYPELOC(Class, Type) - A TypeLoc referring to a type part of
-// a declarator, excluding type-spec types.
-//
//===----------------------------------------------------------------------===//
#ifndef UNQUAL_TYPELOC
-# define UNQUAL_TYPELOC(Class, Base, Type) TYPELOC(Class, Base)
+# define UNQUAL_TYPELOC(Class, Base) TYPELOC(Class, Base)
#endif
#ifndef ABSTRACT_TYPELOC
-# define ABSTRACT_TYPELOC(Class) TYPELOC(Class, TypeLoc)
-#endif
-
-#ifndef TYPESPEC_TYPELOC
-# define TYPESPEC_TYPELOC(Class, Type) UNQUAL_TYPELOC(Class, TypeSpecLoc, Type)
+# define ABSTRACT_TYPELOC(Class, Base) UNQUAL_TYPELOC(Class, Base)
#endif
-#ifndef DECLARATOR_TYPELOC
-# define DECLARATOR_TYPELOC(Class, Type) UNQUAL_TYPELOC(Class, DeclaratorLoc, Type)
-#endif
-
-TYPESPEC_TYPELOC(DefaultTypeSpecLoc, Type)
-TYPESPEC_TYPELOC(TypedefLoc, TypedefType)
-TYPESPEC_TYPELOC(ObjCInterfaceLoc, ObjCInterfaceType)
-TYPESPEC_TYPELOC(ObjCProtocolListLoc, ObjCProtocolListType)
-DECLARATOR_TYPELOC(PointerLoc, PointerType)
-DECLARATOR_TYPELOC(BlockPointerLoc, BlockPointerType)
-DECLARATOR_TYPELOC(MemberPointerLoc, MemberPointerType)
-DECLARATOR_TYPELOC(ReferenceLoc, ReferenceType)
-DECLARATOR_TYPELOC(FunctionLoc, FunctionType)
-DECLARATOR_TYPELOC(ArrayLoc, ArrayType)
-ABSTRACT_TYPELOC(DeclaratorLoc)
-ABSTRACT_TYPELOC(TypeSpecLoc)
-TYPELOC(QualifiedLoc, TypeLoc)
-
+TYPELOC(Qualified, TypeLoc)
+#define TYPE(Class, Base) UNQUAL_TYPELOC(Class, Base##Loc)
+#define ABSTRACT_TYPE(Class, Base) ABSTRACT_TYPELOC(Class, Base##Loc)
+#include "clang/AST/TypeNodes.def"
#undef DECLARATOR_TYPELOC
#undef TYPESPEC_TYPELOC
diff --git a/include/clang/AST/TypeLocVisitor.h b/include/clang/AST/TypeLocVisitor.h
index a96757f123e8..a62bb3f853bc 100644
--- a/include/clang/AST/TypeLocVisitor.h
+++ b/include/clang/AST/TypeLocVisitor.h
@@ -15,46 +15,38 @@
#include "clang/AST/TypeLoc.h"
#include "clang/AST/TypeVisitor.h"
+#include "llvm/Support/ErrorHandling.h"
namespace clang {
-#define DISPATCH(CLASS) \
- return static_cast<ImplClass*>(this)->Visit ## CLASS(cast<CLASS>(TyLoc))
+#define DISPATCH(CLASSNAME) \
+ return static_cast<ImplClass*>(this)-> \
+ Visit##CLASSNAME(cast<CLASSNAME>(TyLoc))
template<typename ImplClass, typename RetTy=void>
class TypeLocVisitor {
- class TypeDispatch : public TypeVisitor<TypeDispatch, RetTy> {
- ImplClass *Impl;
- UnqualTypeLoc TyLoc;
-
- public:
- TypeDispatch(ImplClass *impl, UnqualTypeLoc &tyLoc)
- : Impl(impl), TyLoc(tyLoc) { }
-#define TYPELOC(CLASS, BASE)
-#define ABSTRACT_TYPELOC(CLASS)
-#define UNQUAL_TYPELOC(CLASS, PARENT, TYPE) \
- RetTy Visit##TYPE(TYPE *) { \
- return Impl->Visit##CLASS(reinterpret_cast<CLASS&>(TyLoc)); \
- }
-#include "clang/AST/TypeLocNodes.def"
- };
-
public:
RetTy Visit(TypeLoc TyLoc) {
- if (isa<QualifiedLoc>(TyLoc))
- return static_cast<ImplClass*>(this)->
- VisitQualifiedLoc(cast<QualifiedLoc>(TyLoc));
-
- return Visit(cast<UnqualTypeLoc>(TyLoc));
+ switch (TyLoc.getTypeLocClass()) {
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
+#define TYPELOC(CLASS, PARENT) \
+ case TypeLoc::CLASS: DISPATCH(CLASS##TypeLoc);
+#include "clang/AST/TypeLocNodes.def"
+ }
+ llvm::llvm_unreachable("unexpected type loc class!");
}
RetTy Visit(UnqualTypeLoc TyLoc) {
- TypeDispatch TD(static_cast<ImplClass*>(this), TyLoc);
- return TD.Visit(TyLoc.getSourceTypePtr());
+ switch (TyLoc.getTypeLocClass()) {
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
+#define TYPELOC(CLASS, PARENT) \
+ case TypeLoc::CLASS: DISPATCH(CLASS##TypeLoc);
+#include "clang/AST/TypeLocNodes.def"
+ }
}
#define TYPELOC(CLASS, PARENT) \
- RetTy Visit##CLASS(CLASS TyLoc) { \
+ RetTy Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
DISPATCH(PARENT); \
}
#include "clang/AST/TypeLocNodes.def"
diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def
index 6c6bd20e8528..c2721236af02 100644
--- a/include/clang/AST/TypeNodes.def
+++ b/include/clang/AST/TypeNodes.def
@@ -62,8 +62,6 @@ TYPE(RValueReference, ReferenceType)
TYPE(MemberPointer, Type)
ABSTRACT_TYPE(Array, Type)
TYPE(ConstantArray, ArrayType)
-NON_CANONICAL_TYPE(ConstantArrayWithExpr, ConstantArrayType)
-NON_CANONICAL_TYPE(ConstantArrayWithoutExpr, ConstantArrayType)
TYPE(IncompleteArray, ArrayType)
TYPE(VariableArray, ArrayType)
DEPENDENT_TYPE(DependentSizedArray, ArrayType)
@@ -82,12 +80,12 @@ TYPE(Record, TagType)
TYPE(Enum, TagType)
NON_CANONICAL_TYPE(Elaborated, Type)
DEPENDENT_TYPE(TemplateTypeParm, Type)
+NON_CANONICAL_TYPE(SubstTemplateTypeParm, Type)
TYPE(TemplateSpecialization, Type)
NON_CANONICAL_TYPE(QualifiedName, Type)
DEPENDENT_TYPE(Typename, Type)
TYPE(ObjCInterface, Type)
TYPE(ObjCObjectPointer, Type)
-NON_CANONICAL_TYPE(ObjCProtocolList, Type)
// These types are always leaves in the type hierarchy.
#ifdef LEAF_TYPE
@@ -95,7 +93,6 @@ LEAF_TYPE(Enum)
LEAF_TYPE(Builtin)
LEAF_TYPE(FixedWidthInt)
LEAF_TYPE(ObjCInterface)
-LEAF_TYPE(ObjCObjectPointer)
LEAF_TYPE(TemplateTypeParm)
#undef LEAF_TYPE
#endif
diff --git a/include/clang/Analysis/PathSensitive/AnalysisContext.h b/include/clang/Analysis/PathSensitive/AnalysisContext.h
index ffe282d3caa3..8e02ccf38209 100644
--- a/include/clang/Analysis/PathSensitive/AnalysisContext.h
+++ b/include/clang/Analysis/PathSensitive/AnalysisContext.h
@@ -60,6 +60,9 @@ public:
~AnalysisContextManager();
AnalysisContext *getContext(const Decl *D);
+
+ // Discard all previously created AnalysisContexts.
+ void clear();
};
class LocationContext : public llvm::FoldingSetNode {
@@ -155,12 +158,17 @@ class LocationContextManager {
llvm::FoldingSet<LocationContext> Contexts;
public:
+ ~LocationContextManager();
+
StackFrameContext *getStackFrame(AnalysisContext *ctx,
const LocationContext *parent,
const Stmt *s);
ScopeContext *getScope(AnalysisContext *ctx, const LocationContext *parent,
const Stmt *s);
+
+ /// Discard all previously created LocationContext objects.
+ void clear();
};
} // end clang namespace
diff --git a/include/clang/Analysis/PathSensitive/AnalysisManager.h b/include/clang/Analysis/PathSensitive/AnalysisManager.h
index e97f80576a8b..1a64f56ee8a4 100644
--- a/include/clang/Analysis/PathSensitive/AnalysisManager.h
+++ b/include/clang/Analysis/PathSensitive/AnalysisManager.h
@@ -65,6 +65,11 @@ public:
AScope(ScopeDecl), DisplayedFunction(!displayProgress),
VisualizeEGDot(vizdot), VisualizeEGUbi(vizubi), PurgeDead(purge),
EagerlyAssume(eager), TrimGraph(trim) {}
+
+ void ClearContexts() {
+ LocCtxMgr.clear();
+ AnaCtxMgr.clear();
+ }
StoreManagerCreator getStoreManagerCreator() {
return CreateStoreMgr;
diff --git a/include/clang/Analysis/PathSensitive/Store.h b/include/clang/Analysis/PathSensitive/Store.h
index 3ff253d0abf3..7a462c579f9f 100644
--- a/include/clang/Analysis/PathSensitive/Store.h
+++ b/include/clang/Analysis/PathSensitive/Store.h
@@ -141,9 +141,12 @@ public:
const VarDecl *VD,
const LocationContext *LC) = 0;
+ typedef llvm::DenseSet<SymbolRef> InvalidatedSymbols;
+
virtual const GRState *InvalidateRegion(const GRState *state,
const MemRegion *R,
- const Expr *E, unsigned Count) = 0;
+ const Expr *E, unsigned Count,
+ InvalidatedSymbols *IS) = 0;
// FIXME: Make out-of-line.
virtual const GRState *setExtent(const GRState *state,
diff --git a/include/clang/Analysis/Support/BumpVector.h b/include/clang/Analysis/Support/BumpVector.h
index a5e11a100665..b23a80ed481a 100644
--- a/include/clang/Analysis/Support/BumpVector.h
+++ b/include/clang/Analysis/Support/BumpVector.h
@@ -27,16 +27,16 @@
namespace clang {
class BumpVectorContext {
- llvm::PointerIntPair<llvm::BumpPtrAllocator*, 1, bool> Alloc;
+ llvm::PointerIntPair<llvm::BumpPtrAllocator*, 1> Alloc;
public:
/// Construct a new BumpVectorContext that creates a new BumpPtrAllocator
/// and destroys it when the BumpVectorContext object is destroyed.
- BumpVectorContext() : Alloc(new llvm::BumpPtrAllocator(), true) {}
+ BumpVectorContext() : Alloc(new llvm::BumpPtrAllocator(), 1) {}
/// Construct a new BumpVectorContext that reuses an existing
/// BumpPtrAllocator. This BumpPtrAllocator is not destroyed when the
/// BumpVectorContext object is destroyed.
- BumpVectorContext(llvm::BumpPtrAllocator &A) : Alloc(&A, false) {}
+ BumpVectorContext(llvm::BumpPtrAllocator &A) : Alloc(&A, 0) {}
~BumpVectorContext() {
if (Alloc.getInt())
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
index 380192e9dae6..005aab3fa6a1 100644
--- a/include/clang/Basic/Diagnostic.h
+++ b/include/clang/Basic/Diagnostic.h
@@ -15,6 +15,7 @@
#define LLVM_CLANG_DIAGNOSTIC_H
#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/type_traits.h"
#include <string>
#include <vector>
@@ -43,7 +44,7 @@ namespace clang {
DIAG_START_PARSE = DIAG_START_LEX + 300,
DIAG_START_AST = DIAG_START_PARSE + 300,
DIAG_START_SEMA = DIAG_START_AST + 100,
- DIAG_START_ANALYSIS = DIAG_START_SEMA + 1000,
+ DIAG_START_ANALYSIS = DIAG_START_SEMA + 1100,
DIAG_UPPER_LIMIT = DIAG_START_ANALYSIS + 100
};
@@ -107,7 +108,7 @@ public:
/// \brief Create a code modification hint that inserts the given
/// code string at a specific location.
static CodeModificationHint CreateInsertion(SourceLocation InsertionLoc,
- const std::string &Code) {
+ llvm::StringRef Code) {
CodeModificationHint Hint;
Hint.InsertionLoc = InsertionLoc;
Hint.CodeToInsert = Code;
@@ -125,7 +126,7 @@ public:
/// \brief Create a code modification hint that replaces the given
/// source range with the given code string.
static CodeModificationHint CreateReplacement(SourceRange RemoveRange,
- const std::string &Code) {
+ llvm::StringRef Code) {
CodeModificationHint Hint;
Hint.RemoveRange = RemoveRange;
Hint.InsertionLoc = RemoveRange.getBegin();
@@ -163,6 +164,10 @@ public:
ak_nestednamespec, // NestedNameSpecifier *
ak_declcontext // DeclContext *
};
+
+ /// ArgumentValue - This typedef represents on argument value, which is a
+ /// union discriminated by ArgumentKind, with a value.
+ typedef std::pair<ArgumentKind, intptr_t> ArgumentValue;
private:
unsigned char AllExtensionsSilenced; // Used by __extension__
@@ -202,10 +207,17 @@ private:
/// ArgToStringFn - A function pointer that converts an opaque diagnostic
/// argument to a strings. This takes the modifiers and argument that was
/// present in the diagnostic.
+ ///
+ /// The PrevArgs array (whose length is NumPrevArgs) indicates the previous
+ /// arguments formatted for this diagnostic. Implementations of this function
+ /// can use this information to avoid redundancy across arguments.
+ ///
/// This is a hack to avoid a layering violation between libbasic and libsema.
typedef void (*ArgToStringFnTy)(ArgumentKind Kind, intptr_t Val,
const char *Modifier, unsigned ModifierLen,
const char *Argument, unsigned ArgumentLen,
+ const ArgumentValue *PrevArgs,
+ unsigned NumPrevArgs,
llvm::SmallVectorImpl<char> &Output,
void *Cookie);
void *ArgToStringCookie;
@@ -310,9 +322,10 @@ public:
void ConvertArgToString(ArgumentKind Kind, intptr_t Val,
const char *Modifier, unsigned ModLen,
const char *Argument, unsigned ArgLen,
+ const ArgumentValue *PrevArgs, unsigned NumPrevArgs,
llvm::SmallVectorImpl<char> &Output) const {
- ArgToStringFn(Kind, Val, Modifier, ModLen, Argument, ArgLen, Output,
- ArgToStringCookie);
+ ArgToStringFn(Kind, Val, Modifier, ModLen, Argument, ArgLen,
+ PrevArgs, NumPrevArgs, Output, ArgToStringCookie);
}
void SetArgToStringFn(ArgToStringFnTy Fn, void *Cookie) {
@@ -546,7 +559,7 @@ public:
/// return Diag(...);
operator bool() const { return true; }
- void AddString(const std::string &S) const {
+ void AddString(llvm::StringRef S) const {
assert(NumArgs < Diagnostic::MaxArguments &&
"Too many arguments to diagnostic!");
if (DiagObj) {
@@ -581,7 +594,7 @@ public:
};
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- const std::string &S) {
+ llvm::StringRef S) {
DB.AddString(S);
return DB;
}
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index 6971df50cb55..19b0ea3932a5 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -201,6 +201,9 @@ def warn_expected_implementation : Warning<
"@end must appear in an @implementation context">;
def error_property_ivar_decl : Error<
"property synthesize requires specification of an ivar">;
+def warn_semicolon_before_method_nody : Warning<
+ "semicolon before method body is ignored">,
+ InGroup<DiagGroup<"semicolon-before-method-body">>;
def err_expected_field_designator : Error<
"expected a field designator, such as '.field = 4'">;
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index b1222a3f84eb..7a87e244f77c 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -383,6 +383,8 @@ def note_ambig_member_ref_object_type : Note<
"lookup in the object type %0 refers here">;
def note_ambig_member_ref_scope : Note<
"lookup from the current scope refers here">;
+def err_qualified_member_nonclass : Error<
+ "qualified member access refers to a member in %0">;
// C++ class members
def err_storageclass_invalid_for_member : Error<
@@ -785,9 +787,9 @@ def err_ovl_template_candidate : Note<
def err_ovl_candidate_deleted : Note<
"candidate function has been explicitly %select{made unavailable|deleted}0">;
def err_ovl_builtin_binary_candidate : Note<
- "built-in candidate operator %0 (%1, %2)">;
+ "built-in candidate %0">;
def err_ovl_builtin_unary_candidate : Note<
- "built-in candidate operator %0 (%1)">;
+ "built-in candidate %0">;
def err_ovl_no_viable_function_in_init : Error<
"no matching constructor for initialization of %0">;
def err_ovl_ambiguous_init : Error<"call to constructor of %0 is ambiguous">;
@@ -1112,7 +1114,17 @@ def err_explicit_instantiation_without_qualified_id_quals : Error<
"qualifier in explicit instantiation of '%0%1' requires a template-id">;
def err_explicit_instantiation_unqualified_wrong_namespace : Error<
"explicit instantiation of %q0 must occur in %1">;
-
+def err_explicit_instantiation_undefined_member : Error<
+ "explicit instantiation of undefined %select{member class|member function|"
+ "static data member}0 %1 of class template %2">;
+def err_explicit_instantiation_undefined_func_template : Error<
+ "explicit instantiation of undefined function template %0">;
+def err_explicit_instantiation_declaration_after_definition : Error<
+ "explicit instantiation declaration (with 'extern') follows explicit "
+ "instantiation definition (without 'extern')">;
+def note_explicit_instantiation_definition_here : Note<
+ "explicit instantiation definition is here">;
+
// C++ typename-specifiers
def err_typename_nested_not_found : Error<"no type named %0 in %1">;
def err_typename_nested_not_type : Error<
@@ -1734,7 +1746,9 @@ def err_not_tag_in_scope : Error<
def err_cannot_form_pointer_to_member_of_reference_type : Error<
"cannot form a pointer-to-member to member %0 of reference type %1">;
-
+def err_incomplete_object_call : Error<
+ "incomplete type in call to object of type %0">;
+
def warn_condition_is_assignment : Warning<"using the result of an "
"assignment as a condition without parentheses">,
InGroup<Parentheses>;
@@ -2156,6 +2170,8 @@ def err_break_not_in_loop_or_switch : Error<
def err_default_not_in_switch : Error<
"'default' statement not in switch statement">;
def err_case_not_in_switch : Error<"'case' statement not in switch statement">;
+def warn_bool_switch_condition : Warning<
+ "switch condition is a bool">;
def warn_case_value_overflow : Warning<
"overflow converting case value to switch condition type (%0 to %1)">;
def err_duplicate_case : Error<"duplicate case value '%0'">;
@@ -2187,7 +2203,7 @@ def ext_return_has_expr : ExtWarn<
def ext_return_has_void_expr : Extension<
"void %select{function|method}1 %0 should not return void expression">;
def warn_noreturn_function_has_return_expr : Warning<
- "function %0 declared 'noreturn' should not return">, DefaultError,
+ "function %0 declared 'noreturn' should not return">,
InGroup<DiagGroup<"invalid-noreturn">>;
def warn_falloff_noreturn_function : Warning<
"function declared 'noreturn' should not return">,
diff --git a/include/clang/Basic/FileManager.h b/include/clang/Basic/FileManager.h
index 7c9113c497ef..5e7ac4f3c859 100644
--- a/include/clang/Basic/FileManager.h
+++ b/include/clang/Basic/FileManager.h
@@ -71,16 +71,38 @@ public:
}
};
-// FIXME: This is a lightweight shim that is used by FileManager to cache
-// 'stat' system calls. We will use it with PTH to identify if caching
-// stat calls in PTH files is a performance win.
+/// \brief Abstract interface for introducing a FileManager cache for 'stat'
+/// system calls, which is used by precompiled and pretokenized headers to
+/// improve performance.
class StatSysCallCache {
+protected:
+ llvm::OwningPtr<StatSysCallCache> NextStatCache;
+
public:
virtual ~StatSysCallCache() {}
- virtual int stat(const char *path, struct stat *buf) = 0;
+ virtual int stat(const char *path, struct stat *buf) {
+ if (getNextStatCache())
+ return getNextStatCache()->stat(path, buf);
+
+ return ::stat(path, buf);
+ }
+
+ /// \brief Sets the next stat call cache in the chain of stat caches.
+ /// Takes ownership of the given stat cache.
+ void setNextStatCache(StatSysCallCache *Cache) {
+ NextStatCache.reset(Cache);
+ }
+
+ /// \brief Retrieve the next stat call cache in the chain.
+ StatSysCallCache *getNextStatCache() { return NextStatCache.get(); }
+
+ /// \brief Retrieve the next stat call cache in the chain, transferring
+ /// ownership of this cache (and, transitively, all of the remaining caches)
+ /// to the caller.
+ StatSysCallCache *takeNextStatCache() { return NextStatCache.take(); }
};
-/// \brief A stat listener that can be used by FileManager to keep
+/// \brief A stat "cache" that can be used by FileManager to keep
/// track of the results of stat() calls that occur throughout the
/// execution of the front end.
class MemorizeStatCalls : public StatSysCallCache {
@@ -144,13 +166,22 @@ public:
FileManager();
~FileManager();
- /// setStatCache - Installs the provided StatSysCallCache object within
- /// the FileManager. Ownership of this object is transferred to the
- /// FileManager.
- void setStatCache(StatSysCallCache *statCache) {
- StatCache.reset(statCache);
- }
-
+ /// \brief Installs the provided StatSysCallCache object within
+ /// the FileManager.
+ ///
+ /// Ownership of this object is transferred to the FileManager.
+ ///
+ /// \param statCache the new stat cache to install. Ownership of this
+ /// object is transferred to the FileManager.
+ ///
+ /// \param AtBeginning whether this new stat cache must be installed at the
+ /// beginning of the chain of stat caches. Otherwise, it will be added to
+ /// the end of the chain.
+ void addStatCache(StatSysCallCache *statCache, bool AtBeginning = false);
+
+ /// \brief Removes the provided StatSysCallCache object from the file manager.
+ void removeStatCache(StatSysCallCache *statCache);
+
/// getDirectory - Lookup, cache, and verify the specified directory. This
/// returns null if the directory doesn't exist.
///
diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h
index 84c2fc910d11..e06dfbb2cf1b 100644
--- a/include/clang/Basic/IdentifierTable.h
+++ b/include/clang/Basic/IdentifierTable.h
@@ -75,13 +75,13 @@ public:
/// This is intended to be used for string literals only: II->isStr("foo").
template <std::size_t StrLen>
bool isStr(const char (&Str)[StrLen]) const {
- return getLength() == StrLen-1 && !memcmp(getName(), Str, StrLen-1);
+ return getLength() == StrLen-1 && !memcmp(getNameStart(), Str, StrLen-1);
}
- /// getName - Return the actual string for this identifier. The returned
- /// string is properly null terminated.
+ /// getNameStart - Return the beginning of the actual string for this
+ /// identifier. The returned string is properly null terminated.
///
- const char *getName() const {
+ const char *getNameStart() const {
if (Entry) return Entry->getKeyData();
// FIXME: This is gross. It would be best not to embed specific details
// of the PTH file format here.
@@ -101,8 +101,12 @@ public:
// std::pair<IdentifierInfo, const char*>, where internal pointer
// points to the external string data.
const char* p = ((std::pair<IdentifierInfo, const char*>*) this)->second-2;
- return (((unsigned) p[0])
- | (((unsigned) p[1]) << 8)) - 1;
+ return (((unsigned) p[0]) | (((unsigned) p[1]) << 8)) - 1;
+ }
+
+ /// getName - Return the actual identifier string.
+ llvm::StringRef getName() const {
+ return llvm::StringRef(getNameStart(), getLength());
}
/// hasMacroDefinition - Return true if this identifier is #defined to some
@@ -232,6 +236,8 @@ public:
/// Unlike the version in IdentifierTable, this returns a pointer instead
/// of a reference. If the pointer is NULL then the IdentifierInfo cannot
/// be found.
+ //
+ // FIXME: Move to StringRef API.
virtual IdentifierInfo* get(const char *NameStart, const char *NameEnd) = 0;
};
@@ -333,8 +339,11 @@ public:
return *II;
}
+ IdentifierInfo &CreateIdentifierInfo(llvm::StringRef Name) {
+ return CreateIdentifierInfo(Name.begin(), Name.end());
+ }
- IdentifierInfo &get(const llvm::StringRef& Name) {
+ IdentifierInfo &get(llvm::StringRef Name) {
return get(Name.begin(), Name.end());
}
@@ -463,7 +472,7 @@ public:
const IdentifierInfo *Name) {
llvm::SmallString<100> SelectorName;
SelectorName = "set";
- SelectorName.append(Name->getName(), Name->getName()+Name->getLength());
+ SelectorName += Name->getName();
SelectorName[3] = toupper(SelectorName[3]);
IdentifierInfo *SetterName =
&Idents.get(SelectorName.data(),
diff --git a/include/clang/Basic/OnDiskHashTable.h b/include/clang/Basic/OnDiskHashTable.h
index 65245167d8d5..2184bf3c457c 100644
--- a/include/clang/Basic/OnDiskHashTable.h
+++ b/include/clang/Basic/OnDiskHashTable.h
@@ -25,27 +25,6 @@
namespace clang {
-// Bernstein hash function:
-// This is basically copy-and-paste from StringMap. This likely won't
-// stay here, which is why I didn't both to expose this function from
-// String Map.
-inline unsigned BernsteinHash(const char* x) {
- unsigned int R = 0;
- for ( ; *x != '\0' ; ++x) R = R * 33 + *x;
- return R + (R >> 5);
-}
-
-inline unsigned BernsteinHash(const char* x, unsigned n) {
- unsigned int R = 0;
- for (unsigned i = 0 ; i < n ; ++i, ++x) R = R * 33 + *x;
- return R + (R >> 5);
-}
-
-inline unsigned BernsteinHashPartial(const char* x, unsigned n, unsigned R) {
- for (unsigned i = 0 ; i < n ; ++i, ++x) R = R * 33 + *x;
- return R + (R >> 5);
-}
-
namespace io {
typedef uint32_t Offset;
diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h
index 7eb988f005ec..8a69cba066b3 100644
--- a/include/clang/Basic/SourceManager.h
+++ b/include/clang/Basic/SourceManager.h
@@ -685,26 +685,19 @@ public:
///
void PrintStats() const;
- // Iteration over the source location entry table.
- typedef std::vector<SrcMgr::SLocEntry>::const_iterator sloc_entry_iterator;
-
- sloc_entry_iterator sloc_entry_begin() const {
- return SLocEntryTable.begin();
- }
-
- sloc_entry_iterator sloc_entry_end() const {
- return SLocEntryTable.end();
- }
-
unsigned sloc_entry_size() const { return SLocEntryTable.size(); }
- const SrcMgr::SLocEntry &getSLocEntry(FileID FID) const {
- assert(FID.ID < SLocEntryTable.size() && "Invalid id");
+ const SrcMgr::SLocEntry &getSLocEntry(unsigned ID) const {
+ assert(ID < SLocEntryTable.size() && "Invalid id");
if (ExternalSLocEntries &&
- FID.ID < SLocEntryLoaded.size() &&
- !SLocEntryLoaded[FID.ID])
- ExternalSLocEntries->ReadSLocEntry(FID.ID);
- return SLocEntryTable[FID.ID];
+ ID < SLocEntryLoaded.size() &&
+ !SLocEntryLoaded[ID])
+ ExternalSLocEntries->ReadSLocEntry(ID);
+ return SLocEntryTable[ID];
+ }
+
+ const SrcMgr::SLocEntry &getSLocEntry(FileID FID) const {
+ return getSLocEntry(FID.ID);
}
unsigned getNextOffset() const { return NextOffset; }
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
index a1e0a17c882e..b88e2aaba383 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -83,7 +83,7 @@ public:
};
protected:
IntType SizeType, IntMaxType, UIntMaxType, PtrDiffType, IntPtrType, WCharType,
- Char16Type, Char32Type, Int64Type;
+ WIntType, Char16Type, Char32Type, Int64Type;
public:
IntType getSizeType() const { return SizeType; }
IntType getIntMaxType() const { return IntMaxType; }
@@ -93,10 +93,20 @@ public:
}
IntType getIntPtrType() const { return IntPtrType; }
IntType getWCharType() const { return WCharType; }
+ IntType getWIntType() const { return WIntType; }
IntType getChar16Type() const { return Char16Type; }
IntType getChar32Type() const { return Char32Type; }
IntType getInt64Type() const { return Int64Type; }
+
+ /// getTypeWidth - Return the width (in bits) of the specified integer type
+ /// enum. For example, SignedInt -> getIntWidth().
+ unsigned getTypeWidth(IntType T) const;
+
+ /// getTypeSigned - Return whether an integer types is signed. Returns true if
+ /// the type is signed; false otherwise.
+ bool getTypeSigned(IntType T) const;
+
/// getPointerWidth - Return the width of pointers on this target, for the
/// specified address space.
uint64_t getPointerWidth(unsigned AddrSpace) const {
@@ -185,6 +195,10 @@ public:
/// For example, SignedShort -> "short".
static const char *getTypeName(IntType T);
+ /// getTypeConstantSuffix - Return the constant suffix for the specified
+ /// integer type enum. For example, SignedLong -> "L".
+ static const char *getTypeConstantSuffix(IntType T);
+
///===---- Other target property query methods --------------------------===//
/// getTargetDefines - Appends the target-specific #define values for this
@@ -192,6 +206,7 @@ public:
virtual void getTargetDefines(const LangOptions &Opts,
std::vector<char> &DefineBuffer) const = 0;
+
/// 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.
diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h
index 89eb3b8821ca..9573777b5f6f 100644
--- a/include/clang/Frontend/ASTUnit.h
+++ b/include/clang/Frontend/ASTUnit.h
@@ -16,6 +16,8 @@
#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/OwningPtr.h"
+#include "clang/Frontend/TextDiagnosticBuffer.h"
+#include "clang/Basic/FileManager.h"
#include <string>
namespace clang {
@@ -23,6 +25,7 @@ namespace clang {
class FileEntry;
class SourceManager;
class Diagnostic;
+ class TextDiagnosticBuffer;
class HeaderSearch;
class TargetInfo;
class Preprocessor;
@@ -32,18 +35,27 @@ namespace clang {
/// \brief Utility class for loading a ASTContext from a PCH file.
///
class ASTUnit {
- Diagnostic &Diags;
+ Diagnostic Diags;
+ FileManager FileMgr;
+
SourceManager SourceMgr;
llvm::OwningPtr<HeaderSearch> HeaderInfo;
llvm::OwningPtr<TargetInfo> Target;
llvm::OwningPtr<Preprocessor> PP;
llvm::OwningPtr<ASTContext> Ctx;
-
+ bool tempFile;
+
+ // OnlyLocalDecls - when true, walking this AST should only visit declarations
+ // that come from the AST itself, not from included precompiled headers.
+ // FIXME: This is temporary; eventually, CIndex will always do this.
+ bool OnlyLocalDecls;
+
ASTUnit(const ASTUnit&); // DO NOT IMPLEMENT
ASTUnit &operator=(const ASTUnit &); // DO NOT IMPLEMENT
- ASTUnit(Diagnostic &_Diag);
+ ASTUnit();
public:
+ ASTUnit(DiagnosticClient *diagClient = NULL);
~ASTUnit();
const SourceManager &getSourceManager() const { return SourceMgr; }
@@ -58,14 +70,23 @@ public:
const Diagnostic &getDiagnostic() const { return Diags; }
Diagnostic &getDiagnostic() { return Diags; }
- FileManager &getFileManager();
+ const FileManager &getFileManager() const { return FileMgr; }
+ FileManager &getFileManager() { return FileMgr; }
+
const std::string &getOriginalSourceFileName();
+ const std::string &getPCHFileName();
+ void unlinkTemporaryFile() { tempFile = true; }
+
+ bool getOnlyLocalDecls() const { return OnlyLocalDecls; }
+
/// \brief Create a ASTUnit from a PCH file.
///
/// \param Filename - The PCH file to load.
///
- /// \param Diags - The Diagnostic implementation to use.
+ /// \param diagClient - The diagnostics client to use. Specify NULL
+ /// to use a default client that emits warnings/errors to standard error.
+ /// The ASTUnit objects takes ownership of this object.
///
/// \param FileMgr - The FileManager to use.
///
@@ -74,9 +95,10 @@ public:
///
/// \returns - The initialized ASTUnit or null if the PCH failed to load.
static ASTUnit *LoadFromPCHFile(const std::string &Filename,
- Diagnostic &Diags,
- FileManager &FileMgr,
- std::string *ErrMsg = 0);
+ std::string *ErrMsg = 0,
+ DiagnosticClient *diagClient = NULL,
+ bool OnlyLocalDecls = false,
+ bool UseBumpAllocator = false);
};
} // namespace clang
diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h
index 716780e68a52..1e953d671226 100644
--- a/include/clang/Frontend/PCHBitCodes.h
+++ b/include/clang/Frontend/PCHBitCodes.h
@@ -86,38 +86,33 @@ namespace clang {
PREPROCESSOR_BLOCK_ID,
/// \brief The block containing the definitions of all of the
- /// types used within the PCH file.
- TYPES_BLOCK_ID,
-
- /// \brief The block containing the definitions of all of the
- /// declarations stored in the PCH file.
- DECLS_BLOCK_ID
+ /// types and decls used within the PCH file.
+ DECLTYPES_BLOCK_ID
};
/// \brief Record types that occur within the PCH block itself.
enum PCHRecordTypes {
- /// \brief Offset of each type within the types block.
+ /// \brief Record code for the offsets of each type.
///
/// The TYPE_OFFSET constant describes the record that occurs
- /// within the block identified by TYPE_OFFSETS_BLOCK_ID within
- /// the PCH file. The record itself is an array of offsets that
- /// point into the types block (identified by TYPES_BLOCK_ID in
- /// the PCH file). The index into the array is based on the ID
+ /// within the PCH block. The record itself is an array of offsets that
+ /// point into the declarations and types block (identified by
+ /// DECLTYPES_BLOCK_ID). The index into the array is based on the ID
/// of a type. For a given type ID @c T, the lower three bits of
/// @c T are its qualifiers (const, volatile, restrict), as in
/// the QualType class. The upper bits, after being shifted and
/// subtracting NUM_PREDEF_TYPE_IDS, are used to index into the
/// TYPE_OFFSET block to determine the offset of that type's
- /// corresponding record within the TYPES_BLOCK_ID block.
+ /// corresponding record within the DECLTYPES_BLOCK_ID block.
TYPE_OFFSET = 1,
/// \brief Record code for the offsets of each decl.
///
/// The DECL_OFFSET constant describes the record that occurs
- /// within the block identifier by DECL_OFFSETS_BLOCK_ID within
- /// the PCH file. The record itself is an array of offsets that
- /// point into the declarations block (identified by
- /// DECLS_BLOCK_ID). The declaration ID is an index into this
+ /// within the block identified by DECL_OFFSETS_BLOCK_ID within
+ /// the PCH block. The record itself is an array of offsets that
+ /// point into the declarations and types block (identified by
+ /// DECLTYPES_BLOCK_ID). The declaration ID is an index into this
/// record, after subtracting one to account for the use of
/// declaration ID 0 for a NULL declaration pointer. Index 0 is
/// reserved for the translation unit declaration.
@@ -353,8 +348,8 @@ namespace clang {
/// \brief Record codes for each kind of type.
///
- /// These constants describe the records that can occur within a
- /// block identified by TYPES_BLOCK_ID in the PCH file. Each
+ /// These constants describe the type records that can occur within a
+ /// block identified by DECLTYPES_BLOCK_ID in the PCH file. Each
/// constant describes a record for a specific type class in the
/// AST.
enum TypeCode {
@@ -402,16 +397,12 @@ namespace clang {
TYPE_OBJC_INTERFACE = 21,
/// \brief An ObjCObjectPointerType record.
TYPE_OBJC_OBJECT_POINTER = 22,
- /// \brief An ObjCProtocolListType record.
- TYPE_OBJC_PROTOCOL_LIST = 23,
/// \brief a DecltypeType record.
- TYPE_DECLTYPE = 24,
- /// \brief A ConstantArrayWithExprType record.
- TYPE_CONSTANT_ARRAY_WITH_EXPR = 25,
- /// \brief A ConstantArrayWithoutExprType record.
- TYPE_CONSTANT_ARRAY_WITHOUT_EXPR = 26,
+ TYPE_DECLTYPE = 23,
/// \brief An ElaboratedType record.
- TYPE_ELABORATED = 27
+ TYPE_ELABORATED = 24,
+ /// \brief A SubstTemplateTypeParmType record.
+ TYPE_SUBST_TEMPLATE_TYPE_PARM = 25
};
/// \brief The type IDs for special types constructed by semantic
@@ -443,18 +434,22 @@ namespace clang {
/// \brief Objective-C "id" redefinition type
SPECIAL_TYPE_OBJC_ID_REDEFINITION = 10,
/// \brief Objective-C "Class" redefinition type
- SPECIAL_TYPE_OBJC_CLASS_REDEFINITION = 11
+ SPECIAL_TYPE_OBJC_CLASS_REDEFINITION = 11,
+ /// \brief Block descriptor type for Blocks CodeGen
+ SPECIAL_TYPE_BLOCK_DESCRIPTOR = 12,
+ /// \brief Block extedned descriptor type for Blocks CodeGen
+ SPECIAL_TYPE_BLOCK_EXTENDED_DESCRIPTOR = 13
};
/// \brief Record codes for each kind of declaration.
///
- /// These constants describe the records that can occur within a
- /// declarations block (identified by DECLS_BLOCK_ID). Each
+ /// These constants describe the declaration records that can occur within
+ /// a declarations block (identified by DECLS_BLOCK_ID). Each
/// constant describes a record for a specific declaration class
/// in the AST.
enum DeclCode {
/// \brief Attributes attached to a declaration.
- DECL_ATTR = 1,
+ DECL_ATTR = 50,
/// \brief A TranslationUnitDecl record.
DECL_TRANSLATION_UNIT,
/// \brief A TypedefDecl record.
@@ -529,14 +524,14 @@ namespace clang {
/// \brief Record codes for each kind of statement or expression.
///
/// These constants describe the records that describe statements
- /// or expressions. These records can occur within either the type
- /// or declaration blocks, so they begin with record values of
- /// 50. Each constant describes a record for a specific
- /// statement or expression class in the AST.
+ /// or expressions. These records occur within type and declarations
+ /// block, so they begin with record values of 100. Each constant
+ /// describes a record for a specific statement or expression class in the
+ /// AST.
enum StmtCode {
/// \brief A marker record that indicates that we are at the end
/// of an expression.
- STMT_STOP = 50,
+ STMT_STOP = 100,
/// \brief A NULL expression.
STMT_NULL_PTR,
/// \brief A NullStmt record.
diff --git a/include/clang/Frontend/PCHReader.h b/include/clang/Frontend/PCHReader.h
index 1230e3753e04..cc16970b0040 100644
--- a/include/clang/Frontend/PCHReader.h
+++ b/include/clang/Frontend/PCHReader.h
@@ -169,6 +169,11 @@ private:
/// \brief The AST context into which we'll read the PCH file.
ASTContext *Context;
+ /// \brief The PCH stat cache installed by this PCHReader, if any.
+ ///
+ /// The dynamic type of this stat cache is always PCHStatCache
+ void *StatCache;
+
/// \brief The AST consumer.
ASTConsumer *Consumer;
@@ -492,8 +497,8 @@ public:
/// \param isysroot If non-NULL, the system include path specified by the
/// user. This is only used with relocatable PCH files. If non-NULL,
/// a relocatable PCH file will use the default path "/".
- PCHReader(SourceManager &SourceMgr, FileManager &FileMgr,
- Diagnostic &Diags, const char *isysroot = 0);
+ PCHReader(SourceManager &SourceMgr, FileManager &FileMgr,
+ Diagnostic &Diags, const char *isysroot = 0);
~PCHReader();
/// \brief Load the precompiled header designated by the given file
@@ -513,6 +518,9 @@ public:
/// \brief Sets and initializes the given Context.
void InitializeContext(ASTContext &Context);
+ /// \brief Retrieve the name of the PCH file
+ const std::string &getFileName() { return FileName; }
+
/// \brief Retrieve the name of the original source file name
const std::string &getOriginalSourceFile() { return OriginalFileName; }
@@ -534,6 +542,10 @@ public:
/// comments in the source code.
virtual void ReadComments(std::vector<SourceRange> &Comments);
+ /// \brief Reads a declarator info from the given record.
+ virtual DeclaratorInfo *GetDeclaratorInfo(const RecordData &Record,
+ unsigned &Idx);
+
/// \brief Resolve a type ID into a type, potentially building a new
/// type.
virtual QualType GetType(pch::TypeID ID);
diff --git a/include/clang/Frontend/PCHWriter.h b/include/clang/Frontend/PCHWriter.h
index a807cd7c4d1f..728e138d9e7c 100644
--- a/include/clang/Frontend/PCHWriter.h
+++ b/include/clang/Frontend/PCHWriter.h
@@ -73,6 +73,33 @@ private:
/// \brief The bitstream writer used to emit this precompiled header.
llvm::BitstreamWriter &Stream;
+ /// \brief Stores a declaration or a type to be written to the PCH file.
+ class DeclOrType {
+ public:
+ DeclOrType(Decl *D) : Stored(D), IsType(false) { }
+ DeclOrType(QualType T) : Stored(T.getAsOpaquePtr()), IsType(true) { }
+
+ bool isType() const { return IsType; }
+ bool isDecl() const { return !IsType; }
+
+ QualType getType() const {
+ assert(isType() && "Not a type!");
+ return QualType::getFromOpaquePtr(Stored);
+ }
+
+ Decl *getDecl() const {
+ assert(isDecl() && "Not a decl!");
+ return static_cast<Decl *>(Stored);
+ }
+
+ private:
+ void *Stored;
+ bool IsType;
+ };
+
+ /// \brief The declarations and types to emit.
+ std::queue<DeclOrType> DeclTypesToEmit;
+
/// \brief Map that provides the ID numbers of each declaration within
/// the output stream.
///
@@ -85,10 +112,6 @@ private:
/// the declaration's ID.
std::vector<uint32_t> DeclOffsets;
- /// \brief Queue containing the declarations that we still need to
- /// emit.
- std::queue<Decl *> DeclsToEmit;
-
/// \brief Map that provides the ID numbers of each type within the
/// output stream.
///
@@ -107,10 +130,6 @@ private:
/// \brief The type ID that will be assigned to the next new type.
pch::TypeID NextTypeID;
- /// \brief Queue containing the types that we still need to
- /// emit.
- std::queue<QualType> TypesToEmit;
-
/// \brief Map that provides the ID numbers of each identifier in
/// the output stream.
///
@@ -189,18 +208,17 @@ private:
void WritePreprocessor(const Preprocessor &PP);
void WriteComments(ASTContext &Context);
void WriteType(QualType T);
- void WriteTypesBlock(ASTContext &Context);
uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC);
uint64_t WriteDeclContextVisibleBlock(ASTContext &Context, DeclContext *DC);
- void WriteDeclsBlock(ASTContext &Context);
void WriteMethodPool(Sema &SemaRef);
void WriteIdentifierTable(Preprocessor &PP);
void WriteAttributeRecord(const Attr *Attr);
unsigned ParmVarDeclAbbrev;
void WriteDeclsBlockAbbrevs();
-
+ void WriteDecl(ASTContext &Context, Decl *D);
+
public:
/// \brief Create a new precompiled header writer that outputs to
/// the given bitstream.
@@ -254,6 +272,9 @@ public:
/// \brief Emit a reference to a type.
void AddTypeRef(QualType T, RecordData &Record);
+ /// \brief Emits a reference to a declarator info.
+ void AddDeclaratorInfo(DeclaratorInfo *DInfo, RecordData &Record);
+
/// \brief Emit a reference to a declaration.
void AddDeclRef(const Decl *D, RecordData &Record);
diff --git a/include/clang/Index/ASTLocation.h b/include/clang/Index/ASTLocation.h
index 9620ec5dbd4f..fc18dae1a20c 100644
--- a/include/clang/Index/ASTLocation.h
+++ b/include/clang/Index/ASTLocation.h
@@ -91,7 +91,7 @@ public:
ASTLocation(const Decl *parentDecl, TypeLoc tyLoc)
: ParentDecl(const_cast<Decl*>(parentDecl), N_Type) {
if (tyLoc) {
- Ty.TyPtr = tyLoc.getSourceType().getAsOpaquePtr();
+ Ty.TyPtr = tyLoc.getType().getAsOpaquePtr();
Ty.Data = tyLoc.getOpaqueData();
} else
ParentDecl.setPointer(0);
@@ -124,8 +124,8 @@ public:
return TypeLoc(QualType::getFromOpaquePtr(Ty.TyPtr), Ty.Data);
}
- Decl *dyn_AsDecl() const { return getKind() == N_Decl ? D : 0; }
- Stmt *dyn_AsStmt() const { return getKind() == N_Stmt ? Stm : 0; }
+ Decl *dyn_AsDecl() const { return isValid() && getKind() == N_Decl ? D : 0; }
+ Stmt *dyn_AsStmt() const { return isValid() && getKind() == N_Stmt ? Stm : 0; }
NamedRef dyn_AsNamedRef() const {
return getKind() == N_Type ? AsNamedRef() : NamedRef();
}
diff --git a/include/clang/Index/Indexer.h b/include/clang/Index/Indexer.h
index 8b1d2dd38bff..361e729feab2 100644
--- a/include/clang/Index/Indexer.h
+++ b/include/clang/Index/Indexer.h
@@ -14,13 +14,11 @@
#ifndef LLVM_CLANG_INDEX_INDEXER_H
#define LLVM_CLANG_INDEX_INDEXER_H
-#include "clang/Frontend/TextDiagnosticBuffer.h"
#include "clang/Index/IndexProvider.h"
#include "clang/Index/Entity.h"
#include "clang/Index/GlobalSelector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/DenseMap.h"
-#include "clang/Basic/FileManager.h"
#include <map>
namespace clang {
@@ -39,16 +37,10 @@ public:
typedef std::map<GlobalSelector, TUSetTy> SelMapTy;
explicit Indexer(Program &prog) :
- Prog(prog), Diags(&DiagClient) { }
+ Prog(prog) { }
Program &getProgram() const { return Prog; }
- Diagnostic &getDiagnostics() { return Diags; }
- const Diagnostic &getDiagnostics() const { return Diags; }
-
- FileManager &getFileManager() { return FileMgr; }
- const FileManager &getFileManager() const { return FileMgr; }
-
/// \brief Find all Entities and map them to the given translation unit.
void IndexAST(TranslationUnit *TU);
@@ -59,9 +51,6 @@ public:
private:
Program &Prog;
- TextDiagnosticBuffer DiagClient;
- Diagnostic Diags;
- FileManager FileMgr;
MapTy Map;
CtxTUMapTy CtxTUMap;
diff --git a/include/clang/Index/Utils.h b/include/clang/Index/Utils.h
index e78ef8a15563..36cf56dea203 100644
--- a/include/clang/Index/Utils.h
+++ b/include/clang/Index/Utils.h
@@ -18,7 +18,8 @@
namespace clang {
class ASTContext;
class SourceLocation;
-
+ class Decl;
+
namespace idx {
class ASTLocation;
@@ -26,7 +27,8 @@ namespace idx {
///
/// \returns the resolved ASTLocation or an invalid ASTLocation if the source
/// location could not be resolved.
-ASTLocation ResolveLocationInAST(ASTContext &Ctx, SourceLocation Loc);
+ASTLocation ResolveLocationInAST(ASTContext &Ctx, SourceLocation Loc,
+ Decl *RelativeToDecl = 0);
} // end namespace idx
diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h
index 1ee14701fa2d..050b3f42e4cd 100644
--- a/include/clang/Parse/Action.h
+++ b/include/clang/Parse/Action.h
@@ -1390,6 +1390,34 @@ public:
return ExprEmpty();
}
+ /// \brief Parsed a C++ destructor reference that refers to a type.
+ ///
+ /// This action is used when parsing a destructor reference that uses a
+ /// template-id, e.g.,
+ ///
+ /// \code
+ /// t->~Tmpl<T1, T2>
+ /// \endcode
+ ///
+ /// \param S the scope in which the destructor reference occurs.
+ /// \param Base the base object of the destructor reference expression.
+ /// \param OpLoc the location of the operator ('.' or '->').
+ /// \param OpKind the kind of the destructor reference operator ('.' or '->').
+ /// \param TypeRange the source range that covers the destructor type.
+ /// \param Type the type that is being destroyed.
+ /// \param SS the scope specifier that precedes the destructor name.
+ /// \param HasTrailingLParen whether the destructor name is followed by a '('.
+ virtual OwningExprResult
+ ActOnDestructorReferenceExpr(Scope *S, ExprArg Base,
+ SourceLocation OpLoc,
+ tok::TokenKind OpKind,
+ SourceRange TypeRange,
+ TypeTy *Type,
+ const CXXScopeSpec &SS,
+ bool HasTrailingLParen) {
+ return ExprEmpty();
+ }
+
/// ActOnOverloadedOperatorReferenceExpr - Parsed an overloaded operator
/// reference, for example:
///
@@ -1691,9 +1719,25 @@ public:
/// possibly checking well-formedness of the template arguments. It does not
/// imply the declaration of any entity.
///
+ /// \param SS The scope specifier that may precede the template name.
+ ///
/// \param Template A template whose specialization results in a
/// function or a dependent template.
- virtual OwningExprResult ActOnTemplateIdExpr(TemplateTy Template,
+ ///
+ /// \param TemplateNameLoc The location of the template name.
+ ///
+ /// \param LAngleLoc The location of the left angle bracket ('<') that starts
+ /// the template argument list.
+ ///
+ /// \param TemplateArgs The template arguments in the template argument list,
+ /// which may be empty.
+ ///
+ /// \param TemplateArgLocs The locations of the template arguments.
+ ///
+ /// \param RAngleLoc The location of the right angle bracket ('>') that
+ /// closes the template argument list.
+ virtual OwningExprResult ActOnTemplateIdExpr(const CXXScopeSpec &SS,
+ TemplateTy Template,
SourceLocation TemplateNameLoc,
SourceLocation LAngleLoc,
ASTTemplateArgsPtr TemplateArgs,